diff --git a/.zuul.yaml b/.zuul.yaml index ffbb235c5..0eac6ec24 100644 --- a/.zuul.yaml +++ b/.zuul.yaml @@ -153,7 +153,8 @@ - monasca-tempest-python3-cassandra - monasca-tempest-python2-java-cassandra - monasca-tempest-python3-java-cassandra - - monascalog-python3-tempest + - monascalog-python3-tempest: + voting: false - build-monasca-docker-image gate: queue: monasca @@ -165,7 +166,6 @@ - monasca-tempest-python3-cassandra - monasca-tempest-python2-java-cassandra - monasca-tempest-python3-java-cassandra - - monascalog-python3-tempest post: jobs: - publish-monasca-api-docker-image diff --git a/lower-constraints.txt b/lower-constraints.txt index b2102cc39..d93b15833 100644 --- a/lower-constraints.txt +++ b/lower-constraints.txt @@ -19,7 +19,7 @@ docutils==0.11 dulwich==0.15.0 eventlet==0.18.2 extras==1.0.0 -falcon==1.0.0 +falcon==2.0.0 fasteners==0.7.0 fixtures==3.0.0 flake8==2.5.5 diff --git a/monasca_api/api/server.py b/monasca_api/api/server.py index ae9c5b5c3..f7f660eea 100644 --- a/monasca_api/api/server.py +++ b/monasca_api/api/server.py @@ -33,6 +33,10 @@ def launch(conf): config.parse_args() app = falcon.API(request_type=request.Request) + # NOTE(dszumski): 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. + app.req_options.strip_url_path_trailing_slash = True versions = simport.load(cfg.CONF.dispatcher.versions)() app.add_route("/", versions) diff --git a/monasca_api/tests/base.py b/monasca_api/tests/base.py index aa1342bd6..024391060 100644 --- a/monasca_api/tests/base.py +++ b/monasca_api/tests/base.py @@ -34,24 +34,6 @@ from monasca_api import policies policy.POLICIES = policies -class MockedAPI(falcon.API): - """MockedAPI - - 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, - response_type=falcon.Response, - middleware=None, - router=None - ) - - class ConfigFixture(oo_cfg.Config): """Mocks configuration""" @@ -96,8 +78,18 @@ class BaseTestCase(oslotest_base.BaseTestCase): cfg.CONF.set_default(k, v, group) -class BaseApiTestCase(BaseTestCase, testing.TestBase): - api_class = MockedAPI +class BaseApiTestCase(BaseTestCase, testing.TestCase): + + def setUp(self): + super(BaseApiTestCase, self).setUp() + # TODO(dszumski): Loading the app from api/server.py seems to make + # more sense here so that we don't have to manually keep the tests in + # sync with it. + self.app = falcon.API(request_type=request.Request) + # NOTE(dszumski): 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 @staticmethod def create_environ(*args, **kwargs): diff --git a/monasca_api/tests/test_alarms.py b/monasca_api/tests/test_alarms.py index fe9da2390..9180517dc 100644 --- a/monasca_api/tests/test_alarms.py +++ b/monasca_api/tests/test_alarms.py @@ -27,7 +27,6 @@ import testtools.matchers as matchers from mock import Mock import oslo_config.fixture -from oslo_serialization import jsonutils import six from monasca_api.common.repositories.model import sub_alarm_definition @@ -124,10 +123,7 @@ class RESTResponseEquals(object): return 'RESTResponseEquals(%s)' % (self.expected,) def match(self, actual): - if len(actual) != 1: - return matchers.Mismatch("Response contains <> 1 item: %r" % actual) - - response_data = jsonutils.loads(actual[0]) + response_data = actual.json if u"links" in response_data: del response_data[u"links"] @@ -176,10 +172,10 @@ class TestAlarmsStateHistory(AlarmTestBase): 'metrics_repository.client.InfluxDBClient')) self.alarms_resource = alarms.AlarmsStateHistory() - self.api.add_route( + self.app.add_route( '/v2.0/alarms/{alarm_id}/state-history/', self.alarms_resource) - self.api.add_route( + self.app.add_route( '/v2.0/alarms/state-history/', self.alarms_resource) def test_alarm_state_history(self): @@ -188,26 +184,25 @@ class TestAlarmsStateHistory(AlarmTestBase): del (expected_elements[u"elements"][0][u"sub_alarms"][0] [u"sub_alarm_expression"][u"metric_definition"]) del expected_elements[u"elements"][0][u"tenant_id"] - response = self.simulate_request( - u'/v2.0/alarms/%s/state-history/' % ALARM_HISTORY[u"alarm_id"], + path=u'/v2.0/alarms/%s/state-history/' % ALARM_HISTORY[u"alarm_id"], headers={ 'X-Roles': CONF.security.default_authorized_roles[0], 'X-Tenant-Id': TENANT_ID, }) - self.assertEqual(self.srmock.status, falcon.HTTP_200) + self.assertEqual(response.status, falcon.HTTP_200) self.assertThat(response, RESTResponseEquals(expected_elements)) def test_alarm_state_history_no_alarm_id(self): expected_elements = {u'elements': []} response = self.simulate_request( - u'/v2.0/alarms/state-history/', + path=u'/v2.0/alarms/state-history/', headers={ 'X-Roles': CONF.security.default_authorized_roles[0], 'X-Tenant-Id': TENANT_ID, }) - self.assertEqual(self.srmock.status, falcon.HTTP_200) + self.assertEqual(response.status, falcon.HTTP_200) self.assertThat(response, RESTResponseEquals(expected_elements)) @@ -220,8 +215,7 @@ class TestAlarmsCount(AlarmTestBase): )).mock self.alarms_count_resource = alarms.AlarmsCount() - - self.api.add_route('/v2.0/alarms/count', + self.app.add_route('/v2.0/alarms/count', self.alarms_count_resource) def test_get_alarm_count(self): @@ -230,13 +224,13 @@ class TestAlarmsCount(AlarmTestBase): return_value.get_alarms_count.return_value = [{'count': 4}] - response = self.simulate_request('/v2.0/alarms/count', + response = self.simulate_request(path='/v2.0/alarms/count', headers={'X-Roles': CONF.security.default_authorized_roles[0], 'X-Tenant-Id': TENANT_ID}, method='GET') - self.assertEqual(self.srmock.status, falcon.HTTP_200) + self.assertEqual(response.status, falcon.HTTP_200) self.assertThat(response, RESTResponseEquals(expected_elements)) def test_get_alarm_count_state_parameter(self): @@ -245,14 +239,14 @@ class TestAlarmsCount(AlarmTestBase): return_value.get_alarms_count.return_value = [{'count': 4}] - response = self.simulate_request('/v2.0/alarms/count', + response = self.simulate_request(path='/v2.0/alarms/count', headers={'X-Roles': CONF.security.default_authorized_roles[0], 'X-Tenant-Id': TENANT_ID}, method='GET', query_string='state=OK') - self.assertEqual(self.srmock.status, falcon.HTTP_200) + self.assertEqual(response.status, falcon.HTTP_200) self.assertThat(response, RESTResponseEquals(expected_elements)) def test_get_alarm_count_severity_parameter(self): @@ -261,14 +255,14 @@ class TestAlarmsCount(AlarmTestBase): return_value.get_alarms_count.return_value = [{'count': 4}] - response = self.simulate_request('/v2.0/alarms/count', + response = self.simulate_request(path='/v2.0/alarms/count', headers={'X-Roles': CONF.security.default_authorized_roles[0], 'X-Tenant-Id': TENANT_ID}, method='GET', query_string='severity=LOW') - self.assertEqual(self.srmock.status, falcon.HTTP_200) + self.assertEqual(response.status, falcon.HTTP_200) self.assertThat(response, RESTResponseEquals(expected_elements)) def test_get_alarm_count_group_by_parameter(self): @@ -280,14 +274,14 @@ class TestAlarmsCount(AlarmTestBase): return_value.get_alarms_count.return_value = [{'metric_name': u'cpu.idle_perc', 'count': 2}, {'metric_name': u'cpu.sys_mem', 'count': 1}] - response = self.simulate_request('/v2.0/alarms/count', + response = self.simulate_request(path='/v2.0/alarms/count', headers={'X-Roles': CONF.security.default_authorized_roles[0], 'X-Tenant-Id': TENANT_ID}, method='GET', query_string='group_by=metric_name') - self.assertEqual(self.srmock.status, falcon.HTTP_200) + self.assertEqual(response.status, falcon.HTTP_200) self.assertThat(response, RESTResponseEquals(expected_elements)) expected_elements = {'columns': ['count', 'metric_name', 'dimension_name'], @@ -301,14 +295,14 @@ class TestAlarmsCount(AlarmTestBase): 'dimension_name': 'hostname', 'count': 1}] - response = self.simulate_request('/v2.0/alarms/count', + response = self.simulate_request(path='/v2.0/alarms/count', headers={'X-Roles': CONF.security.default_authorized_roles[0], 'X-Tenant-Id': TENANT_ID}, method='GET', query_string='group_by=metric_name,dimension_name') - self.assertEqual(self.srmock.status, falcon.HTTP_200) + self.assertEqual(response.status, falcon.HTTP_200) self.assertThat(response, RESTResponseEquals(expected_elements)) def test_get_alarm_count_incorrect_group_by_parameter(self): @@ -317,13 +311,14 @@ class TestAlarmsCount(AlarmTestBase): return_value.get_alarms_count.return_value = [{'metric_name': u'cpu.idle_perc', 'count': 2}, {'metric_name': u'cpu.sys_mem', 'count': 1}] - self.simulate_request('/v2.0/alarms/count', - headers={'X-Roles': CONF.security.default_authorized_roles[0], - 'X-Tenant-Id': TENANT_ID}, - method='GET', - query_string='group_by=hahahah') + response = self.simulate_request( + path='/v2.0/alarms/count', + headers={'X-Roles': CONF.security.default_authorized_roles[0], + 'X-Tenant-Id': TENANT_ID}, + method='GET', + query_string='group_by=hahahah') - self.assertEqual(self.srmock.status, falcon.HTTP_422) + self.assertEqual(response.status, falcon.HTTP_422) def test_get_alarm_count_offset(self): return_value = self.alarms_get_alarms_count_mock.return_value @@ -332,13 +327,13 @@ class TestAlarmsCount(AlarmTestBase): return_value.get_alarms_count.return_value = [{'metric_name': u'cpu.idle_perc', 'count': 2}] - response = self.simulate_request('/v2.0/alarms/count', + response = self.simulate_request(path='/v2.0/alarms/count', headers={'X-Roles': CONF.security.default_authorized_roles[0], 'X-Tenant-Id': TENANT_ID}, method='GET', query_string='group_by=metric_name&offset=1') - self.assertEqual(self.srmock.status, falcon.HTTP_200) + self.assertEqual(response.status, falcon.HTTP_200) self.assertThat(response, RESTResponseEquals(expected_elements)) def test_get_alarm_count_incorrect_offset(self): @@ -348,13 +343,13 @@ class TestAlarmsCount(AlarmTestBase): return_value.get_alarms_count.return_value = [{'metric_name': u'cpu.idle_perc', 'count': 2}] - response = self.simulate_request('/v2.0/alarms/count', + response = self.simulate_request(path='/v2.0/alarms/count', headers={'X-Roles': CONF.security.default_authorized_roles[0], 'X-Tenant-Id': TENANT_ID}, method='GET', query_string='group_by=metric_name&offset=hahahah') - self.assertEqual(self.srmock.status, falcon.HTTP_422) + self.assertEqual(response.status, falcon.HTTP_422) self.assertThat(response, RESTResponseEquals(expected_elements)) def test_get_alarm_count_limit_parameter(self): @@ -363,27 +358,27 @@ class TestAlarmsCount(AlarmTestBase): return_value.get_alarms_count.return_value = [{'count': 4}] - response = self.simulate_request('/v2.0/alarms/count', + response = self.simulate_request(path='/v2.0/alarms/count', headers={'X-Roles': CONF.security.default_authorized_roles[0], 'X-Tenant-Id': TENANT_ID}, method='GET', query_string='limit=1') - self.assertEqual(self.srmock.status, falcon.HTTP_200) + self.assertEqual(response.status, falcon.HTTP_200) self.assertThat(response, RESTResponseEquals(expected_elements)) return_value.get_alarms_count.return_value = [{'count': 4}] expected_elements = {'counts': [], 'columns': ['count']} - response = self.simulate_request('/v2.0/alarms/count', + response = self.simulate_request(path='/v2.0/alarms/count', headers={'X-Roles': CONF.security.default_authorized_roles[0], 'X-Tenant-Id': TENANT_ID}, method='GET', query_string='limit=0') - self.assertEqual(self.srmock.status, falcon.HTTP_200) + self.assertEqual(response.status, falcon.HTTP_200) self.assertThat(response, RESTResponseEquals(expected_elements)) def test_get_alarm_count_when_count_is_zero(self): @@ -392,24 +387,24 @@ class TestAlarmsCount(AlarmTestBase): return_value.get_alarms_count.return_value = [{'count': 0}] - response = self.simulate_request('/v2.0/alarms/count', + response = self.simulate_request(path='/v2.0/alarms/count', headers={'X-Roles': CONF.security.default_authorized_roles[0], 'X-Tenant-Id': TENANT_ID}, method='GET', query_string='group_by=metric_name') - self.assertEqual(self.srmock.status, falcon.HTTP_200) + self.assertEqual(response.status, falcon.HTTP_200) self.assertThat(response, RESTResponseEquals(expected_elements)) expected_elements = {'columns': ['count'], 'counts': [[0]]} - response = self.simulate_request('/v2.0/alarms/count', + response = self.simulate_request(path='/v2.0/alarms/count', headers={'X-Roles': CONF.security.default_authorized_roles[0], 'X-Tenant-Id': TENANT_ID}, method='GET') - self.assertEqual(self.srmock.status, falcon.HTTP_200) + self.assertEqual(response.status, falcon.HTTP_200) self.assertThat(response, RESTResponseEquals(expected_elements)) @@ -422,10 +417,9 @@ class TestAlarms(AlarmTestBase): )).mock self.alarms_resource = alarms.Alarms() - - self.api.add_route('/v2.0/alarms', + self.app.add_route('/v2.0/alarms', self.alarms_resource) - self.api.add_route('/v2.0/alarms/{alarm_id}', + self.app.add_route('/v2.0/alarms/{alarm_id}', self.alarms_resource) def test_alarms_get_alarms(self): @@ -469,13 +463,13 @@ class TestAlarms(AlarmTestBase): 'state_updated_timestamp': '2015-03-14T09:26:53Z', 'updated_timestamp': '2015-03-14T09:26:53Z'}]} - response = self.simulate_request('/v2.0/alarms', + response = self.simulate_request(path='/v2.0/alarms', headers={'X-Roles': CONF.security.default_authorized_roles[0], 'X-Tenant-Id': TENANT_ID}, method='GET') - self.assertEqual(self.srmock.status, falcon.HTTP_200) + self.assertEqual(response.status, falcon.HTTP_200) self.assertThat(response, RESTResponseEquals(expected_alarms)) def test_alarms_get_alarm(self): @@ -517,13 +511,13 @@ class TestAlarms(AlarmTestBase): 'state_updated_timestamp': '2015-03-14T09:26:53Z', 'updated_timestamp': '2015-03-14T09:26:53Z'} - response = self.simulate_request('/v2.0/alarms/1', + response = self.simulate_request(path='/v2.0/alarms/1', headers={'X-Roles': CONF.security.default_authorized_roles[0], 'X-Tenant-Id': TENANT_ID}, method='GET') - self.assertEqual(self.srmock.status, falcon.HTTP_200) + self.assertEqual(response.status, falcon.HTTP_200) self.assertThat(response, RESTResponseEquals(expected_alarms)) def test_alarms_get_alarms_state_parameter(self): @@ -566,14 +560,14 @@ class TestAlarms(AlarmTestBase): 'state': 'OK', 'state_updated_timestamp': '2015-03-14T09:26:53Z', 'updated_timestamp': '2015-03-14T09:26:53Z'}]} - response = self.simulate_request('/v2.0/alarms', + response = self.simulate_request(path='/v2.0/alarms', headers={'X-Roles': CONF.security.default_authorized_roles[0], 'X-Tenant-Id': TENANT_ID}, method='GET', query_string='state=OK') - self.assertEqual(self.srmock.status, falcon.HTTP_200) + self.assertEqual(response.status, falcon.HTTP_200) self.assertThat(response, RESTResponseEquals(expected_alarms)) def test_alarms_get_alarms_severity_parameter(self): @@ -616,14 +610,14 @@ class TestAlarms(AlarmTestBase): 'state': 'OK', 'state_updated_timestamp': '2015-03-14T09:26:53Z', 'updated_timestamp': '2015-03-14T09:26:53Z'}]} - response = self.simulate_request('/v2.0/alarms', + response = self.simulate_request(path='/v2.0/alarms', headers={'X-Roles': CONF.security.default_authorized_roles[0], 'X-Tenant-Id': TENANT_ID}, method='GET', query_string='severity=LOW') - self.assertEqual(self.srmock.status, falcon.HTTP_200) + self.assertEqual(response.status, falcon.HTTP_200) self.assertThat(response, RESTResponseEquals(expected_alarms)) def test_alarms_get_alarms_with_offset(self): @@ -666,14 +660,14 @@ class TestAlarms(AlarmTestBase): 'state': 'OK', 'state_updated_timestamp': '2015-03-14T09:26:53Z', 'updated_timestamp': '2015-03-14T09:26:53Z'}]} - response = self.simulate_request('/v2.0/alarms', + response = self.simulate_request(path='/v2.0/alarms', headers={'X-Roles': CONF.security.default_authorized_roles[0], 'X-Tenant-Id': TENANT_ID}, method='GET', query_string='offset=1') - self.assertEqual(self.srmock.status, falcon.HTTP_200) + self.assertEqual(response.status, falcon.HTTP_200) self.assertThat(response, RESTResponseEquals(expected_alarms)) def test_alarms_get_alarms_with_incorrect_offset(self): @@ -692,13 +686,14 @@ class TestAlarms(AlarmTestBase): 'alarm_id': '1', 'lifecycle_state': 'OPEN'}] - self.simulate_request('/v2.0/alarms', - headers={'X-Roles': CONF.security.default_authorized_roles[0], - 'X-Tenant-Id': TENANT_ID}, - method='GET', - query_string='offset=ninccorect_offset') + response = self.simulate_request( + path='/v2.0/alarms', + headers={'X-Roles': CONF.security.default_authorized_roles[0], + 'X-Tenant-Id': TENANT_ID}, + method='GET', + query_string='offset=ninccorect_offset') - self.assertEqual(self.srmock.status, falcon.HTTP_422) + self.assertEqual(response.status, falcon.HTTP_422) def test_alarms_get_alarms_sort_by_parameter(self): return_value = self.alarms_repo_mock.return_value @@ -740,14 +735,14 @@ class TestAlarms(AlarmTestBase): 'state': 'OK', 'state_updated_timestamp': '2015-03-14T09:26:53Z', 'updated_timestamp': '2015-03-14T09:26:53Z'}]} - response = self.simulate_request('/v2.0/alarms', + response = self.simulate_request(path='/v2.0/alarms', headers={'X-Roles': CONF.security.default_authorized_roles[0], 'X-Tenant-Id': TENANT_ID}, method='GET', query_string='sort_by=alarm_id') - self.assertEqual(self.srmock.status, falcon.HTTP_200) + self.assertEqual(response.status, falcon.HTTP_200) self.assertThat(response, RESTResponseEquals(expected_alarms)) def test_alarms_get_alarms_incorrect_sort_by_parameter(self): @@ -766,14 +761,14 @@ class TestAlarms(AlarmTestBase): 'alarm_id': '1', 'lifecycle_state': 'OPEN'}] - self.simulate_request('/v2.0/alarms', - headers={'X-Roles': - CONF.security.default_authorized_roles[0], - 'X-Tenant-Id': TENANT_ID}, - method='GET', - query_string='sort_by=random_string') + response = self.simulate_request(path='/v2.0/alarms', + headers={'X-Roles': + CONF.security.default_authorized_roles[0], + 'X-Tenant-Id': TENANT_ID}, + method='GET', + query_string='sort_by=random_string') - self.assertEqual(self.srmock.status, falcon.HTTP_422) + self.assertEqual(response.status, falcon.HTTP_422) def test_alarms_delete_alarms(self): return_value = self.alarms_repo_mock.return_value @@ -786,13 +781,12 @@ class TestAlarms(AlarmTestBase): 'alarm_id': u'2', 'expression': u'avg(cpu.idle_perc{instance_id=123, service=monitoring}) > 10', 'alarm_definition_id': u'1'}] - - self.simulate_request('/v2.0/alarms/2', - headers={'X-Roles': - CONF.security.default_authorized_roles[0], - 'X-Tenant-Id': TENANT_ID}, - method='DELETE') - self.assertEqual(self.srmock.status, falcon.HTTP_204) + response = self.simulate_request(path='/v2.0/alarms/2', + headers={'X-Roles': + CONF.security.default_authorized_roles[0], + 'X-Tenant-Id': TENANT_ID}, + method='DELETE') + self.assertEqual(response.status, falcon.HTTP_204) def test_alarms_put(self): return_value = self.alarms_repo_mock.return_value @@ -857,14 +851,14 @@ class TestAlarms(AlarmTestBase): u'state_updated_timestamp': u'2019-02-22T12:44:25.850947Z', u'updated_timestamp': u'2019-02-22T12:44:25.850947Z'} - response = self.simulate_request('/v2.0/alarms/2', + response = self.simulate_request(path='/v2.0/alarms/2', headers={'X-Roles': CONF.security.default_authorized_roles[0], 'X-Tenant-Id': TENANT_ID}, method='PUT', body=json.dumps(alarm_new_fields)) - self.assertEqual(self.srmock.status, falcon.HTTP_200) + self.assertEqual(response.status, falcon.HTTP_200) self.assertThat(response, RESTResponseEquals(expected_alarm)) def test_alarms_put_without_link(self): @@ -872,14 +866,14 @@ class TestAlarms(AlarmTestBase): 'lifecycle_state': 'OPEN'} expected_response = {u'description': u"Field 'link' is required", u'title': u'Unprocessable Entity'} - response = self.simulate_request('/v2.0/alarms/2', + response = self.simulate_request(path='/v2.0/alarms/2', headers={'X-Roles': CONF.security.default_authorized_roles[0], 'X-Tenant-Id': TENANT_ID}, method='PUT', body=json.dumps(alarm_new_fields)) - self.assertEqual(self.srmock.status, falcon.HTTP_422) + self.assertEqual(response.status, falcon.HTTP_422) self.assertThat(response, RESTResponseEquals(expected_response)) def test_alarms_put_without_lifecycle_state(self): @@ -887,14 +881,14 @@ class TestAlarms(AlarmTestBase): 'link': 'http://somesite.com/this-alarm-info'} expected_response = {u'description': u"Field 'lifecycle_state' is required", u'title': u'Unprocessable Entity'} - response = self.simulate_request('/v2.0/alarms/2', + response = self.simulate_request(path='/v2.0/alarms/2', headers={'X-Roles': CONF.security.default_authorized_roles[0], 'X-Tenant-Id': TENANT_ID}, method='PUT', body=json.dumps(alarm_new_fields)) - self.assertEqual(self.srmock.status, falcon.HTTP_422) + self.assertEqual(response.status, falcon.HTTP_422) self.assertThat(response, RESTResponseEquals(expected_response)) def test_alarms_put_without_state(self): @@ -902,14 +896,14 @@ class TestAlarms(AlarmTestBase): 'link': 'http://somesite.com/this-alarm-info'} expected_response = {u'description': u"Field 'state' is required", u'title': u'Unprocessable Entity'} - response = self.simulate_request('/v2.0/alarms/2', + response = self.simulate_request(path='/v2.0/alarms/2', headers={'X-Roles': CONF.security.default_authorized_roles[0], 'X-Tenant-Id': TENANT_ID}, method='PUT', body=json.dumps(alarm_new_fields)) - self.assertEqual(self.srmock.status, falcon.HTTP_422) + self.assertEqual(response.status, falcon.HTTP_422) self.assertThat(response, RESTResponseEquals(expected_response)) def test_alarms_patch(self): @@ -975,14 +969,14 @@ class TestAlarms(AlarmTestBase): u'state_updated_timestamp': u'2019-02-22T12:44:25.850947Z', u'updated_timestamp': u'2019-02-22T12:44:25.850947Z'} - response = self.simulate_request('/v2.0/alarms/2', + response = self.simulate_request(path='/v2.0/alarms/2', headers={'X-Roles': CONF.security.default_authorized_roles[0], 'X-Tenant-Id': TENANT_ID}, method='PATCH', body=json.dumps(alarm_new_fields)) - self.assertEqual(self.srmock.status, falcon.HTTP_200) + self.assertEqual(response.status, falcon.HTTP_200) self.assertThat(response, RESTResponseEquals(expected_alarm)) def test_alarms_patch_without_new_fields(self): @@ -1046,14 +1040,14 @@ class TestAlarms(AlarmTestBase): u'state_updated_timestamp': u'2019-02-22T12:44:25.850947Z', u'updated_timestamp': u'2019-02-22T12:44:25.850947Z'} - response = self.simulate_request('/v2.0/alarms/2', + response = self.simulate_request(path='/v2.0/alarms/2', headers={'X-Roles': CONF.security.default_authorized_roles[0], 'X-Tenant-Id': TENANT_ID}, method='PATCH', body=json.dumps(alarm_new_fields)) - self.assertEqual(self.srmock.status, falcon.HTTP_200) + self.assertEqual(response.status, falcon.HTTP_200) self.assertThat(response, RESTResponseEquals(expected_alarm)) @@ -1070,9 +1064,9 @@ class TestAlarmDefinition(AlarmTestBase): self.alarm_definition_resource.send_event = Mock() self._send_event = self.alarm_definition_resource.send_event - self.api.add_route("/v2.0/alarm-definitions/", + self.app.add_route("/v2.0/alarm-definitions/", self.alarm_definition_resource) - self.api.add_route("/v2.0/alarm-definitions/{alarm_definition_id}", + self.app.add_route("/v2.0/alarm-definitions/{alarm_definition_id}", self.alarm_definition_resource) def test_alarm_definition_create(self): @@ -1099,14 +1093,14 @@ class TestAlarmDefinition(AlarmTestBase): u'severity': u'LOW', } - response = self.simulate_request("/v2.0/alarm-definitions/", + response = self.simulate_request(path="/v2.0/alarm-definitions/", headers={'X-Roles': CONF.security.default_authorized_roles[0], 'X-Tenant-Id': TENANT_ID}, method="POST", body=json.dumps(alarm_def)) - self.assertEqual(self.srmock.status, falcon.HTTP_201) + self.assertEqual(response.status, falcon.HTTP_201) self.assertThat(response, RESTResponseEquals(expected_data)) def test_alarm_definition_create_with_valid_expressions(self): @@ -1157,14 +1151,14 @@ class TestAlarmDefinition(AlarmTestBase): for expression in valid_expressions: alarm_def[u'expression'] = expression expected_data[u'expression'] = expression - response = self.simulate_request("/v2.0/alarm-definitions/", + response = self.simulate_request(path="/v2.0/alarm-definitions/", headers={'X-Roles': CONF.security.default_authorized_roles[0], 'X-Tenant-Id': TENANT_ID}, method="POST", body=json.dumps(alarm_def)) - self.assertEqual(self.srmock.status, falcon.HTTP_201, + self.assertEqual(response.status, falcon.HTTP_201, u'Expression {} should have passed'.format(expression)) self.assertThat(response, RESTResponseEquals(expected_data)) @@ -1183,13 +1177,14 @@ class TestAlarmDefinition(AlarmTestBase): for expression in bad_expressions: alarm_def[u'expression'] = expression - self.simulate_request("/v2.0/alarm-definitions/", - headers={'X-Roles': CONF.security.default_authorized_roles[0], - 'X-Tenant-Id': TENANT_ID}, - method="POST", - body=json.dumps(alarm_def)) + response = self.simulate_request( + path="/v2.0/alarm-definitions/", + headers={'X-Roles': CONF.security.default_authorized_roles[0], + 'X-Tenant-Id': TENANT_ID}, + method="POST", + body=json.dumps(alarm_def)) - self.assertEqual(self.srmock.status, '422 Unprocessable Entity', + self.assertEqual(response.status, '422 Unprocessable Entity', u'Expression {} should have failed'.format(expression)) def test_alarm_definition_create_with_occupied_alarm_definition_name(self): @@ -1209,12 +1204,13 @@ class TestAlarmDefinition(AlarmTestBase): u'name': u'Test Definition', u'expression': u'max(test.metric{hostname=host}) gte 1' } - self.simulate_request("/v2.0/alarm-definitions/", - headers={'X-Roles': CONF.security.default_authorized_roles[0], - 'X-Tenant-Id': TENANT_ID}, - method="POST", - body=json.dumps(alarm_def)) - self.assertEqual(self.srmock.status, falcon.HTTP_409) + response = self.simulate_request( + path="/v2.0/alarm-definitions/", + headers={'X-Roles': CONF.security.default_authorized_roles[0], + 'X-Tenant-Id': TENANT_ID}, + method="POST", + body=json.dumps(alarm_def)) + self.assertEqual(response.status, falcon.HTTP_409) def test_alarm_definition_update(self): self.alarm_def_repo_mock.return_value.get_alarm_definitions.return_value = [] @@ -1285,15 +1281,15 @@ class TestAlarmDefinition(AlarmTestBase): u'severity': u'LOW', } - result = self.simulate_request("/v2.0/alarm-definitions/%s" % expected_def[u'id'], + result = self.simulate_request(path="/v2.0/alarm-definitions/%s" % expected_def[u'id'], headers={'X-Roles': CONF.security.default_authorized_roles[0], 'X-Tenant-Id': TENANT_ID}, method="PUT", body=json.dumps(alarm_def)) - self.assertEqual(self.srmock.status, falcon.HTTP_200) - result_def = jsonutils.loads(result[0]) + self.assertEqual(result.status, falcon.HTTP_200) + result_def = result.json self.assertEqual(result_def, expected_def) def test_alarm_definition_patch_incorrect_id(self): @@ -1312,15 +1308,15 @@ class TestAlarmDefinition(AlarmTestBase): alarm_def = { u'name': u'Test Alarm Definition Updated', } - self.simulate_request( - "/v2.0/alarm-definitions/9999999-0001-0001-0001-000000000001", + response = self.simulate_request( + path="/v2.0/alarm-definitions/9999999-0001-0001-0001-000000000001", headers={ 'X-Roles': CONF.security.default_authorized_roles[0], 'X-Tenant-Id': TENANT_ID}, method="PATCH", body=json.dumps(alarm_def)) - self.assertEqual(self.srmock.status, falcon.HTTP_409) + self.assertEqual(response.status, falcon.HTTP_409) def test_alarm_definition_put_incorrect_period_value(self): self.alarm_def_repo_mock.return_value.get_alarm_definitions.return_value = [] @@ -1338,43 +1334,44 @@ class TestAlarmDefinition(AlarmTestBase): u'severity': u'LOW', } - self.simulate_request("/v2.0/alarm-definitions/00000001-0001-0001-0001-000000000001", - headers={'X-Roles': CONF.security.default_authorized_roles[0], - 'X-Tenant-Id': TENANT_ID}, - method="PUT", - body=json.dumps(alarm_def)) + response = self.simulate_request( + path="/v2.0/alarm-definitions/00000001-0001-0001-0001-000000000001", + headers={'X-Roles': CONF.security.default_authorized_roles[0], + 'X-Tenant-Id': TENANT_ID}, + method="PUT", + body=json.dumps(alarm_def)) - self.assertEqual(self.srmock.status, falcon.HTTP_422) + self.assertEqual(response.status, falcon.HTTP_422) def test_alarm_definition_patch_no_id(self): alarm_def = { u'name': u'Test Alarm Definition Updated', } - self.simulate_request( - "/v2.0/alarm-definitions/", + response = self.simulate_request( + path="/v2.0/alarm-definitions/", headers={ 'X-Roles': CONF.security.default_authorized_roles[0], 'X-Tenant-Id': TENANT_ID}, method="PATCH", body=json.dumps(alarm_def)) - self.assertEqual(self.srmock.status, falcon.HTTP_400) + self.assertEqual(response.status, falcon.HTTP_400) def test_alarm_definition_update_no_id(self): alarm_def = { u'name': u'Test Alarm Definition Updated', } - self.simulate_request( - "/v2.0/alarm-definitions/", + response = self.simulate_request( + path="/v2.0/alarm-definitions/", headers={ 'X-Roles': CONF.security.default_authorized_roles[0], 'X-Tenant-Id': TENANT_ID}, method="PUT", body=json.dumps(alarm_def)) - self.assertEqual(self.srmock.status, falcon.HTTP_400) + self.assertEqual(response.status, falcon.HTTP_400) def test_alarm_definition_delete(self): @@ -1400,14 +1397,14 @@ class TestAlarmDefinition(AlarmTestBase): 'sub_alarm_id': '43'}] self.alarm_def_repo_mock.return_value.delete_alarm_definition.return_value = True - self.simulate_request( - '/v2.0/alarm-definitions/00000001-0001-0001-0001-000000000001', + response = self.simulate_request( + path='/v2.0/alarm-definitions/00000001-0001-0001-0001-000000000001', headers={ 'X-Roles': CONF.security.default_authorized_roles[0], 'X-Tenant-Id': TENANT_ID}, method='DELETE') - self.assertEqual(self.srmock.status, falcon.HTTP_204) + self.assertEqual(response.status, falcon.HTTP_204) def test_alarm_definition_delete_alarm_definition_not_exist(self): self.alarm_def_repo_mock.return_value.get_get_sub_alarm_definitions.return_value = [] @@ -1415,25 +1412,25 @@ class TestAlarmDefinition(AlarmTestBase): self.alarm_def_repo_mock.return_value.get_sub_alarms.return_value = [] self.alarm_def_repo_mock.return_value.delete_alarm_definition.return_value = False - self.simulate_request( - '/v2.0/alarm-definitions/00000001-0001-0001-0001-000000000001', + response = self.simulate_request( + path='/v2.0/alarm-definitions/00000001-0001-0001-0001-000000000001', headers={ 'X-Roles': CONF.security.default_authorized_roles[0], 'X-Tenant-Id': TENANT_ID}, method='DELETE') - self.assertEqual(self.srmock.status, falcon.HTTP_404) + self.assertEqual(response.status, falcon.HTTP_404) def test_alarm_definition_delete_no_id(self): - self.simulate_request( - "/v2.0/alarm-definitions/", + response = self.simulate_request( + path="/v2.0/alarm-definitions/", headers={ 'X-Roles': CONF.security.default_authorized_roles[0], 'X-Tenant-Id': TENANT_ID}, method="DELETE") - self.assertEqual(self.srmock.status, falcon.HTTP_400) + self.assertEqual(response.status, falcon.HTTP_400) def test_alarm_definition_patch(self): self.alarm_def_repo_mock.return_value.get_alarm_definitions.return_value = [] @@ -1502,15 +1499,15 @@ class TestAlarmDefinition(AlarmTestBase): u'name': u'Test Alarm Updated', } - result = self.simulate_request("/v2.0/alarm-definitions/%s" % expected_def[u'id'], + result = self.simulate_request(path="/v2.0/alarm-definitions/%s" % expected_def[u'id'], headers={'X-Roles': CONF.security.default_authorized_roles[0], 'X-Tenant-Id': TENANT_ID}, method="PATCH", body=json.dumps(alarm_def)) - self.assertEqual(self.srmock.status, falcon.HTTP_200) - result_def = jsonutils.loads(result[0]) + self.assertEqual(result.status, falcon.HTTP_200) + result_def = result.json self.assertEqual(result_def, expected_def) # If the alarm-definition-updated event does not have all of the # fields set, the Threshold Engine will get confused. For example, @@ -1612,26 +1609,28 @@ class TestAlarmDefinition(AlarmTestBase): u'severity': u'LOW' } - result = self.simulate_request("/v2.0/alarm-definitions/%s" % expected_def[u'id'], + result = self.simulate_request(path="/v2.0/alarm-definitions/%s" % expected_def[u'id'], headers={'X-Roles': CONF.security.default_authorized_roles[0], 'X-Tenant-Id': TENANT_ID}, method="PUT", body=json.dumps(alarm_def)) - self.assertEqual(self.srmock.status, falcon.HTTP_200) - result_def = jsonutils.loads(result[0]) + self.assertEqual(result.status, falcon.HTTP_200) + result_def = result.json self.assertEqual(result_def, expected_def) for key, value in alarm_def.items(): del alarm_def[key] - self.simulate_request("/v2.0/alarm-definitions/%s" % expected_def[u'id'], - headers={'X-Roles': CONF.security.default_authorized_roles[0], - 'X-Tenant-Id': TENANT_ID}, - method="PUT", - body=json.dumps(alarm_def)) - self.assertEqual(self.srmock.status, "422 Unprocessable Entity", + response = self.simulate_request( + path="/v2.0/alarm-definitions/%s" % expected_def[u'id'], + headers={'X-Roles': + CONF.security.default_authorized_roles[0], + 'X-Tenant-Id': TENANT_ID}, + method="PUT", + body=json.dumps(alarm_def)) + self.assertEqual(response.status, "422 Unprocessable Entity", u"should have failed without key {}".format(key)) alarm_def[key] = value @@ -1668,13 +1667,13 @@ class TestAlarmDefinition(AlarmTestBase): } response = self.simulate_request( - '/v2.0/alarm-definitions/%s' % (expected_data[u'id']), + path='/v2.0/alarm-definitions/%s' % (expected_data[u'id']), headers={ 'X-Roles': CONF.security.default_authorized_roles[0], 'X-Tenant-Id': TENANT_ID, }) - self.assertEqual(self.srmock.status, falcon.HTTP_200) + self.assertEqual(response.status, falcon.HTTP_200) self.assertThat(response, RESTResponseEquals(expected_data)) def test_alarm_definition_get_specific_alarm_description_none(self): @@ -1707,13 +1706,13 @@ class TestAlarmDefinition(AlarmTestBase): } response = self.simulate_request( - '/v2.0/alarm-definitions/%s' % (expected_data[u'id']), + path='/v2.0/alarm-definitions/%s' % (expected_data[u'id']), headers={ 'X-Roles': CONF.security.default_authorized_roles[0], 'X-Tenant-Id': TENANT_ID, }) - self.assertEqual(self.srmock.status, falcon.HTTP_200) + self.assertEqual(response.status, falcon.HTTP_200) self.assertThat(response, RESTResponseEquals(expected_data)) def test_get_alarm_definitions_with_multibyte_character(self): @@ -1745,14 +1744,13 @@ class TestAlarmDefinition(AlarmTestBase): } response = self.simulate_request( - '/v2.0/alarm-definitions/%s' % (expected_data[u'id']), + path='/v2.0/alarm-definitions/%s' % (expected_data[u'id']), headers={ 'X-Roles': CONF.security.default_authorized_roles[0], 'X-Tenant-Id': TENANT_ID, } ) - - self.assertEqual(self.srmock.status, falcon.HTTP_200) + self.assertEqual(response.status, falcon.HTTP_200) self.assertThat(response, RESTResponseEquals(expected_data)) def test_alarm_definition_get_alarm_definition_list(self): @@ -1789,56 +1787,56 @@ class TestAlarmDefinition(AlarmTestBase): } response = self.simulate_request( - '/v2.0/alarm-definitions', + path='/v2.0/alarm-definitions', headers={ 'X-Roles': CONF.security.default_authorized_roles[0], 'X-Tenant-Id': TENANT_ID }, query_string='name=Test Alarm') - self.assertEqual(self.srmock.status, falcon.HTTP_200) + self.assertEqual(response.status, falcon.HTTP_200) self.assertThat(response, RESTResponseEquals(expected_data)) response = self.simulate_request( - '/v2.0/alarm-definitions', + path='/v2.0/alarm-definitions', headers={ 'X-Roles': CONF.security.default_authorized_roles[0], 'X-Tenant-Id': TENANT_ID }, query_string='sort_by=name') - self.assertEqual(self.srmock.status, falcon.HTTP_200) + self.assertEqual(response.status, falcon.HTTP_200) self.assertThat(response, RESTResponseEquals(expected_data)) response = self.simulate_request( - '/v2.0/alarm-definitions', + path='/v2.0/alarm-definitions', headers={ 'X-Roles': CONF.security.default_authorized_roles[0], 'X-Tenant-Id': TENANT_ID }, query_string='severity=LOW') - self.assertEqual(self.srmock.status, falcon.HTTP_200) + self.assertEqual(response.status, falcon.HTTP_200) self.assertThat(response, RESTResponseEquals(expected_data)) response = self.simulate_request( - '/v2.0/alarm-definitions', + path='/v2.0/alarm-definitions', headers={ 'X-Roles': CONF.security.default_authorized_roles[0], 'X-Tenant-Id': TENANT_ID }, query_string='offset=1') - self.assertEqual(self.srmock.status, falcon.HTTP_200) + self.assertEqual(response.status, falcon.HTTP_200) self.assertThat(response, RESTResponseEquals(expected_data)) def test_alarm_definition_get_alarm_definition_list_incorrect(self): - self.simulate_request( - '/v2.0/alarm-definitions', + response = self.simulate_request( + path='/v2.0/alarm-definitions', headers={ 'X-Roles': CONF.security.default_authorized_roles[0], 'X-Tenant-Id': TENANT_ID }, query_string='offset=definitelyNotINT') - self.assertEqual(self.srmock.status, falcon.HTTP_422) + self.assertEqual(response.status, falcon.HTTP_422) def test_alarm_definition_get_query_alarm_definition_name(self): alarm_def = { diff --git a/monasca_api/tests/test_healthchecks.py b/monasca_api/tests/test_healthchecks.py index af046c81c..8bbdffcae 100644 --- a/monasca_api/tests/test_healthchecks.py +++ b/monasca_api/tests/test_healthchecks.py @@ -19,7 +19,7 @@ from monasca_api import config from monasca_api.healthcheck import base from monasca_api import healthchecks from monasca_api.tests import base as test_base -from monasca_common.rest import utils + CONF = config.CONF ENDPOINT = '/healthcheck' @@ -32,9 +32,10 @@ class TestHealthChecks(test_base.BaseApiTestCase): if hasattr(CONF, 'sql_engine'): delattr(CONF, 'sql_engine') - def set_route(self): + def setUp(self): + super(TestHealthChecks, self).setUp() self.resources = healthchecks.HealthChecks() - self.api.add_route( + self.app.add_route( ENDPOINT, self.resources ) @@ -43,9 +44,8 @@ class TestHealthChecks(test_base.BaseApiTestCase): @mock.patch( 'monasca_api.healthcheck.metrics_db_check.MetricsDbCheck') def test_should_return_200_for_head(self, metrics_db_check, _): - self.set_route() - self.simulate_request(ENDPOINT, method='HEAD') - self.assertEqual(falcon.HTTP_NO_CONTENT, self.srmock.status) + result = self.simulate_request(path=ENDPOINT, method='HEAD') + self.assertEqual(falcon.HTTP_NO_CONTENT, result.status) @mock.patch('monasca_api.healthcheck.kafka_check.KafkaHealthCheck') @mock.patch( @@ -63,20 +63,18 @@ class TestHealthChecks(test_base.BaseApiTestCase): 'OK') metrics_db_check.health_check.return_value = base.CheckResult(True, 'OK') - self.set_route() self.resources._kafka_check = kafka_check self.resources._alarm_db_check = alarms_db_check self.resources._metrics_db_check = metrics_db_check - response = self.simulate_request(ENDPOINT, + response = 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, response.status) - response = utils.from_json(response) + response = response.json self.assertIn('kafka', response) self.assertIn('alarms_database', response) self.assertIn('metrics_database', response) @@ -118,20 +116,19 @@ class TestHealthChecks(test_base.BaseApiTestCase): service['alarms_db']['healthy'], service['alarms_db']['message']) metrics_db_check.health_check.return_value = base.CheckResult( service['netrics_db']['healthy'], service['netrics_db']['message']) - self.set_route() self.resources._kafka_check = kafka_check self.resources._alarm_db_check = alarms_db_check self.resources._metrics_db_check = metrics_db_check - response = self.simulate_request(ENDPOINT, + response = 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, + response.status) - response = utils.from_json(response) + response = response.json self.assertIn('kafka', response) self.assertIn('alarms_database', response) self.assertIn('metrics_database', response) diff --git a/monasca_api/tests/test_versions.py b/monasca_api/tests/test_versions.py index f4aed3de0..61b714449 100644 --- a/monasca_api/tests/test_versions.py +++ b/monasca_api/tests/test_versions.py @@ -14,7 +14,6 @@ # under the License. import datetime -import json import falcon @@ -24,15 +23,15 @@ from monasca_api.v2.reference import versions class TestVersions(base.BaseApiTestCase): - def before(self): - self.versions_resource = versions.Versions() - self.api.add_route('/versions', self.versions_resource) - self.api.add_route('/versions/{version_id}', self.versions_resource) + def setUp(self): + super(TestVersions, self).setUp() + self.app.add_route('/', versions.Versions()) + self.app.add_route('/{version_id}', versions.Versions()) def test_list_versions(self): - result = self.simulate_request('/versions') - self.assertEqual(self.srmock.status, falcon.HTTP_200) - response = json.loads(result[0].decode('utf-8')) + result = self.simulate_request(path='/') + self.assertEqual(result.status, falcon.HTTP_200) + response = result.json self.assertIsInstance(response, dict) self.assertTrue(set(['links', 'elements']) == set(response)) @@ -42,12 +41,12 @@ class TestVersions(base.BaseApiTestCase): self.assertTrue(set(['rel', 'href']) == set(link)) self.assertEqual(link['rel'], u'self') - self.assertTrue(link['href'].endswith('versions')) + self.assertTrue(link['href'].endswith('/')) def test_valid_version_id(self): - result = self.simulate_request('/versions/v2.0') - self.assertEqual(self.srmock.status, falcon.HTTP_200) - response = json.loads(result[0].decode('utf-8')) + result = self.simulate_request(path='/v2.0') + self.assertEqual(result.status, falcon.HTTP_200) + response = result.json self.assertIsInstance(response, dict) version = response self.assertTrue(set(['id', 'links', 'status', 'updated']) == @@ -63,8 +62,8 @@ class TestVersions(base.BaseApiTestCase): self.assertTrue(set(['rel', 'href']) == set(link)) self.assertEqual(link['rel'], u'self') - self.assertTrue(link['href'].endswith('/versions/v2.0')) + self.assertTrue(link['href'].endswith('/v2.0')) def test_invalid_version_id(self): - self.simulate_request('/versions/v1.0') - self.assertEqual(self.srmock.status, '422 Unprocessable Entity') + result = self.simulate_request(path='/v1.0') + self.assertEqual(result.status, '422 Unprocessable Entity') diff --git a/monasca_api/v2/reference/helpers.py b/monasca_api/v2/reference/helpers.py index 30f5b400d..335d40434 100644 --- a/monasca_api/v2/reference/helpers.py +++ b/monasca_api/v2/reference/helpers.py @@ -40,8 +40,7 @@ def from_json(req): :raises falcon.HTTPBadRequest: """ try: - msg = req.stream.read() - return rest_utils.from_json(msg) + return req.media except Exception as ex: LOG.exception(ex) raise falcon.HTTPBadRequest('Bad request', diff --git a/requirements.txt b/requirements.txt index 1754ab40c..184b4be89 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,7 +13,7 @@ oslo.utils>=3.33.0 # Apache-2.0 python-keystoneclient>=3.8.0 # Apache-2.0 -falcon>=1.0.0 # Apache-2.0 +falcon>=2.0.0 # Apache-2.0 keystonemiddleware>=4.17.0 # Apache-2.0 PasteDeploy>=1.5.0 # MIT pbr!=2.1.0,>=2.0.0 # Apache-2.0 diff --git a/setup.cfg b/setup.cfg index 19cc404d2..5f63ffabb 100644 --- a/setup.cfg +++ b/setup.cfg @@ -29,7 +29,8 @@ data_files = [extras] influxdb = - influxdb>=2.9.2 # MIT + influxdb>=2.9.2,!=5.2.0,!=5.2.1,!=5.2.2;python_version<'3.0' # MIT + influxdb>=2.9.2;python_version>='3.0' # MIT cassandra = cassandra-driver!=3.6.0,>=3.3.0 # Apache-2.0 diff --git a/test-requirements.txt b/test-requirements.txt index dc1282d2a..1133afb44 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -10,7 +10,8 @@ coverage!=4.4,>=4.0 # Apache-2.0 cassandra-driver!=3.6.0,>=3.3.0 # Apache-2.0 fixtures>=3.0.0 # Apache-2.0/BSD httplib2>=0.9.1 # MIT -influxdb>=2.9.2 # MIT +influxdb>=2.9.2,!=5.2.0,!=5.2.1,!=5.2.2;python_version<'3.0' # MIT +influxdb>=2.9.2;python_version>='3.0' # MIT mock>=2.0.0 # BSD funcsigs>=1.0.0;python_version=='2.7' or python_version=='2.6' # Apache-2.0 oslotest>=3.2.0 # Apache-2.0 @@ -25,7 +26,8 @@ tempest>=17.1.0 # Apache-2.0 # documentation doc8>=0.6.0 # Apache-2.0 -sphinx!=1.6.6,!=1.6.7,>=1.6.2 # BSD +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.4.0 # Apache-2.0 reno>=2.5.0 # Apache-2.0 openstackdocstheme>=1.18.1 # Apache-2.0