diff options
-rw-r--r-- | tempest/api/telemetry/base.py | 53 | ||||
-rw-r--r-- | tempest/api/telemetry/test_alarming_api.py (renamed from tempest/api/telemetry/test_telemetry_alarming_api.py) | 32 | ||||
-rw-r--r-- | tempest/api/telemetry/test_alarming_api_negative.py | 14 | ||||
-rw-r--r-- | tempest/clients.py | 8 | ||||
-rwxr-xr-x | tempest/cmd/javelin.py | 7 | ||||
-rw-r--r-- | tempest/config.py | 18 | ||||
-rw-r--r-- | tempest/hacking/ignored_list_T110.txt | 1 | ||||
-rw-r--r-- | tempest/services/telemetry/json/alarming_client.py | 98 | ||||
-rw-r--r-- | tempest/services/telemetry/json/telemetry_client.py | 57 | ||||
-rw-r--r-- | tempest/tests/common/test_service_clients.py | 2 |
10 files changed, 200 insertions, 90 deletions
diff --git a/tempest/api/telemetry/base.py b/tempest/api/telemetry/base.py index 81f00ece0..bbd01f0a3 100644 --- a/tempest/api/telemetry/base.py +++ b/tempest/api/telemetry/base.py @@ -61,18 +61,9 @@ class BaseTelemetryTest(tempest.test.BaseTestCase): cls.glance_v2_notifications = ['image.download', 'image.serve'] cls.server_ids = [] - cls.alarm_ids = [] cls.image_ids = [] @classmethod - def create_alarm(cls, **kwargs): - body = cls.telemetry_client.create_alarm( - name=data_utils.rand_name('telemetry_alarm'), - type='threshold', **kwargs) - cls.alarm_ids.append(body['alarm_id']) - return body - - @classmethod def create_server(cls): tenant_network = cls.get_tenant_network() body, server = compute.create_test_server( @@ -106,7 +97,6 @@ class BaseTelemetryTest(tempest.test.BaseTestCase): @classmethod def resource_cleanup(cls): - cls.cleanup_resources(cls.telemetry_client.delete_alarm, cls.alarm_ids) cls.cleanup_resources(cls.servers_client.delete_server, cls.server_ids) cls.cleanup_resources(cls.image_client.delete_image, cls.image_ids) super(BaseTelemetryTest, cls).resource_cleanup() @@ -153,3 +143,46 @@ class BaseTelemetryAdminTest(BaseTelemetryTest): raise exceptions.TimeoutException( 'Event with query:%s has not been added to the ' 'database within %d seconds' % (query, CONF.compute.build_timeout)) + + +class BaseAlarmingTest(tempest.test.BaseTestCase): + """Base test case class for all Alarming API tests.""" + + credentials = ['primary'] + + @classmethod + def skip_checks(cls): + super(BaseAlarmingTest, cls).skip_checks() + if not CONF.service_available.aodh: + raise cls.skipException("Aodh support is required") + + @classmethod + def setup_clients(cls): + super(BaseAlarmingTest, cls).setup_clients() + cls.alarming_client = cls.os.alarming_client + + @classmethod + def resource_setup(cls): + super(BaseAlarmingTest, cls).resource_setup() + cls.alarm_ids = [] + + @classmethod + def create_alarm(cls, **kwargs): + body = cls.alarming_client.create_alarm( + name=data_utils.rand_name('telemetry_alarm'), + type='threshold', **kwargs) + cls.alarm_ids.append(body['alarm_id']) + return body + + @staticmethod + def cleanup_resources(method, list_of_ids): + for resource_id in list_of_ids: + try: + method(resource_id) + except lib_exc.NotFound: + pass + + @classmethod + def resource_cleanup(cls): + cls.cleanup_resources(cls.alarming_client.delete_alarm, cls.alarm_ids) + super(BaseAlarmingTest, cls).resource_cleanup() diff --git a/tempest/api/telemetry/test_telemetry_alarming_api.py b/tempest/api/telemetry/test_alarming_api.py index 6c84b9808..daa09394a 100644 --- a/tempest/api/telemetry/test_telemetry_alarming_api.py +++ b/tempest/api/telemetry/test_alarming_api.py @@ -17,7 +17,7 @@ from tempest.common.utils import data_utils from tempest import test -class TelemetryAlarmingAPITestJSON(base.BaseTelemetryTest): +class TelemetryAlarmingAPITestJSON(base.BaseAlarmingTest): @classmethod def resource_setup(cls): @@ -32,7 +32,7 @@ class TelemetryAlarmingAPITestJSON(base.BaseTelemetryTest): @test.idempotent_id('1c918e06-210b-41eb-bd45-14676dd77cd6') def test_alarm_list(self): # List alarms - alarm_list = self.telemetry_client.list_alarms() + alarm_list = self.alarming_client.list_alarms() # Verify created alarm in the list fetched_ids = [a['alarm_id'] for a in alarm_list] @@ -46,7 +46,7 @@ class TelemetryAlarmingAPITestJSON(base.BaseTelemetryTest): def test_create_update_get_delete_alarm(self): # Create an alarm alarm_name = data_utils.rand_name('telemetry_alarm') - body = self.telemetry_client.create_alarm( + body = self.alarming_client.create_alarm( name=alarm_name, type='threshold', threshold_rule=self.rule) self.assertEqual(alarm_name, body['name']) alarm_id = body['alarm_id'] @@ -57,7 +57,7 @@ class TelemetryAlarmingAPITestJSON(base.BaseTelemetryTest): 'threshold': 70.0, 'period': 60} alarm_name_updated = data_utils.rand_name('telemetry-alarm-update') - body = self.telemetry_client.update_alarm( + body = self.alarming_client.update_alarm( alarm_id, threshold_rule=new_rule, name=alarm_name_updated, @@ -65,19 +65,19 @@ class TelemetryAlarmingAPITestJSON(base.BaseTelemetryTest): self.assertEqual(alarm_name_updated, body['name']) self.assertDictContainsSubset(new_rule, body['threshold_rule']) # Get and verify details of an alarm after update - body = self.telemetry_client.show_alarm(alarm_id) + body = self.alarming_client.show_alarm(alarm_id) self.assertEqual(alarm_name_updated, body['name']) self.assertDictContainsSubset(new_rule, body['threshold_rule']) # Get history for the alarm and verify the same - body = self.telemetry_client.show_alarm_history(alarm_id) + body = self.alarming_client.show_alarm_history(alarm_id) self.assertEqual("rule change", body[0]['type']) self.assertIn(alarm_name_updated, body[0]['detail']) self.assertEqual("creation", body[1]['type']) self.assertIn(alarm_name, body[1]['detail']) # Delete alarm and verify if deleted - self.telemetry_client.delete_alarm(alarm_id) + self.alarming_client.delete_alarm(alarm_id) self.assertRaises(lib_exc.NotFound, - self.telemetry_client.show_alarm, alarm_id) + self.alarming_client.show_alarm, alarm_id) @test.idempotent_id('aca49486-70bb-4016-87e0-f6131374f741') def test_set_get_alarm_state(self): @@ -86,11 +86,11 @@ class TelemetryAlarmingAPITestJSON(base.BaseTelemetryTest): # Set alarm state and verify new_state =\ [elem for elem in alarm_states if elem != alarm['state']][0] - state = self.telemetry_client.alarm_set_state(alarm['alarm_id'], - new_state) + state = self.alarming_client.alarm_set_state(alarm['alarm_id'], + new_state) self.assertEqual(new_state, state.data) # Get alarm state and verify - state = self.telemetry_client.show_alarm_state(alarm['alarm_id']) + state = self.alarming_client.show_alarm_state(alarm['alarm_id']) self.assertEqual(new_state, state.data) @test.idempotent_id('08d7e45a-1344-4e5c-ba6f-f6cbb77f55b9') @@ -99,13 +99,13 @@ class TelemetryAlarmingAPITestJSON(base.BaseTelemetryTest): "operator": "or"} # Verifies alarm create alarm_name = data_utils.rand_name('combination_alarm') - body = self.telemetry_client.create_alarm(name=alarm_name, - combination_rule=rule, - type='combination') + body = self.alarming_client.create_alarm(name=alarm_name, + combination_rule=rule, + type='combination') self.assertEqual(alarm_name, body['name']) alarm_id = body['alarm_id'] self.assertDictContainsSubset(rule, body['combination_rule']) # Verify alarm delete - self.telemetry_client.delete_alarm(alarm_id) + self.alarming_client.delete_alarm(alarm_id) self.assertRaises(lib_exc.NotFound, - self.telemetry_client.show_alarm, alarm_id) + self.alarming_client.show_alarm, alarm_id) diff --git a/tempest/api/telemetry/test_alarming_api_negative.py b/tempest/api/telemetry/test_alarming_api_negative.py index 06753b078..e9455569d 100644 --- a/tempest/api/telemetry/test_alarming_api_negative.py +++ b/tempest/api/telemetry/test_alarming_api_negative.py @@ -20,7 +20,7 @@ from tempest_lib import exceptions as lib_exc import uuid -class TelemetryAlarmingNegativeTest(base.BaseTelemetryTest): +class TelemetryAlarmingNegativeTest(base.BaseAlarmingTest): """Negative tests for show_alarm, update_alarm, show_alarm_history tests ** show non-existent alarm @@ -34,7 +34,7 @@ class TelemetryAlarmingNegativeTest(base.BaseTelemetryTest): def test_get_non_existent_alarm(self): # get the non-existent alarm non_existent_id = str(uuid.uuid4()) - self.assertRaises(lib_exc.NotFound, self.telemetry_client.show_alarm, + self.assertRaises(lib_exc.NotFound, self.alarming_client.show_alarm, non_existent_id) @test.attr(type=['negative']) @@ -46,14 +46,14 @@ class TelemetryAlarmingNegativeTest(base.BaseTelemetryTest): 'comparison_operator': 'eq', 'threshold': 100.0, 'period': 90} - body = self.telemetry_client.create_alarm( + body = self.alarming_client.create_alarm( name=alarm_name, type='threshold', threshold_rule=rule) alarm_id = body['alarm_id'] - self.telemetry_client.delete_alarm(alarm_id) + self.alarming_client.delete_alarm(alarm_id) # get the deleted alarm - self.assertRaises(lib_exc.NotFound, self.telemetry_client.show_alarm, + self.assertRaises(lib_exc.NotFound, self.alarming_client.show_alarm, alarm_id) # update the deleted alarm @@ -62,10 +62,10 @@ class TelemetryAlarmingNegativeTest(base.BaseTelemetryTest): 'comparison_operator': 'eq', 'threshold': 70, 'period': 50} - self.assertRaises(lib_exc.NotFound, self.telemetry_client.update_alarm, + self.assertRaises(lib_exc.NotFound, self.alarming_client.update_alarm, alarm_id, threshold_rule=updated_rule, name=updated_alarm_name, type='threshold') # delete the deleted alarm - self.assertRaises(lib_exc.NotFound, self.telemetry_client.delete_alarm, + self.assertRaises(lib_exc.NotFound, self.alarming_client.delete_alarm, alarm_id) diff --git a/tempest/clients.py b/tempest/clients.py index 48366a59f..314ee92e4 100644 --- a/tempest/clients.py +++ b/tempest/clients.py @@ -115,6 +115,7 @@ from tempest.services.object_storage.container_client import ContainerClient from tempest.services.object_storage.object_client import ObjectClient from tempest.services.orchestration.json.orchestration_client import \ OrchestrationClient +from tempest.services.telemetry.json.alarming_client import AlarmingClient from tempest.services.telemetry.json.telemetry_client import \ TelemetryClient from tempest.services.volume.json.admin.volume_hosts_client import \ @@ -240,6 +241,13 @@ class Manager(manager.Manager): CONF.identity.region, endpoint_type=CONF.telemetry.endpoint_type, **self.default_params_with_timeout_values) + if CONF.service_available.aodh: + self.alarming_client = AlarmingClient( + self.auth_provider, + CONF.alarming.catalog_type, + CONF.identity.region, + endpoint_type=CONF.alarming.endpoint_type, + **self.default_params_with_timeout_values) if CONF.service_available.glance: self.image_client = ImageClient( self.auth_provider, diff --git a/tempest/cmd/javelin.py b/tempest/cmd/javelin.py index cbaf7566f..3df19fc74 100755 --- a/tempest/cmd/javelin.py +++ b/tempest/cmd/javelin.py @@ -133,6 +133,7 @@ from tempest.services.network.json import network_client from tempest.services.network.json import subnets_client from tempest.services.object_storage import container_client from tempest.services.object_storage import object_client +from tempest.services.telemetry.json import alarming_client from tempest.services.telemetry.json import telemetry_client from tempest.services.volume.json import volumes_client @@ -226,6 +227,12 @@ class OSClient(object): CONF.identity.region, endpoint_type=CONF.telemetry.endpoint_type, **default_params_with_timeout_values) + self.alarming = alarming_client.AlarmingClient( + _auth, + CONF.alarm.catalog_type, + CONF.identity.region, + endpoint_type=CONF.alarm.endpoint_type, + **default_params_with_timeout_values) self.volumes = volumes_client.VolumesClient( _auth, CONF.volume.catalog_type, diff --git a/tempest/config.py b/tempest/config.py index 695c15a26..c9fe38dc1 100644 --- a/tempest/config.py +++ b/tempest/config.py @@ -917,6 +917,20 @@ TelemetryGroup = [ "notification tests") ] +alarming_group = cfg.OptGroup(name='alarming', + title='Alarming Service Options') + +AlarmingGroup = [ + cfg.StrOpt('catalog_type', + default='alarming', + help="Catalog type of the Alarming service."), + cfg.StrOpt('endpoint_type', + default='publicURL', + choices=['public', 'admin', 'internal', + 'publicURL', 'adminURL', 'internalURL'], + help="The endpoint type to use for the alarming service."), +] + telemetry_feature_group = cfg.OptGroup(name='telemetry-feature-enabled', title='Enabled Ceilometer Features') @@ -1127,6 +1141,9 @@ ServiceAvailableGroup = [ cfg.BoolOpt('ceilometer', default=True, help="Whether or not Ceilometer is expected to be available"), + cfg.BoolOpt('aodh', + default=False, + help="Whether or not Aodh is expected to be available"), cfg.BoolOpt('horizon', default=True, help="Whether or not Horizon is expected to be available"), @@ -1273,6 +1290,7 @@ _opts = [ (orchestration_group, OrchestrationGroup), (telemetry_group, TelemetryGroup), (telemetry_feature_group, TelemetryFeaturesGroup), + (alarming_group, AlarmingGroup), (dashboard_group, DashboardGroup), (data_processing_group, DataProcessingGroup), (data_processing_feature_group, DataProcessingFeaturesGroup), diff --git a/tempest/hacking/ignored_list_T110.txt b/tempest/hacking/ignored_list_T110.txt index ee2780085..f52286551 100644 --- a/tempest/hacking/ignored_list_T110.txt +++ b/tempest/hacking/ignored_list_T110.txt @@ -6,6 +6,7 @@ ./tempest/services/identity/v3/json/region_client.py ./tempest/services/messaging/json/messaging_client.py ./tempest/services/object_storage/object_client.py +./tempest/services/telemetry/json/alarming_client.py ./tempest/services/telemetry/json/telemetry_client.py ./tempest/services/volume/json/qos_client.py ./tempest/services/volume/json/backups_client.py diff --git a/tempest/services/telemetry/json/alarming_client.py b/tempest/services/telemetry/json/alarming_client.py new file mode 100644 index 000000000..ce142119b --- /dev/null +++ b/tempest/services/telemetry/json/alarming_client.py @@ -0,0 +1,98 @@ +# Copyright 2014 OpenStack Foundation +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from oslo_serialization import jsonutils as json +from six.moves.urllib import parse as urllib + +from tempest.common import service_client + + +class AlarmingClient(service_client.ServiceClient): + + version = '2' + uri_prefix = "v2" + + def deserialize(self, body): + return json.loads(body.replace("\n", "")) + + def serialize(self, body): + return json.dumps(body) + + def list_alarms(self, query=None): + uri = '%s/alarms' % self.uri_prefix + uri_dict = {} + if query: + uri_dict = {'q.field': query[0], + 'q.op': query[1], + 'q.value': query[2]} + if uri_dict: + uri += "?%s" % urllib.urlencode(uri_dict) + resp, body = self.get(uri) + self.expected_success(200, resp.status) + body = self.deserialize(body) + return service_client.ResponseBodyList(resp, body) + + def show_alarm(self, alarm_id): + uri = '%s/alarms/%s' % (self.uri_prefix, alarm_id) + resp, body = self.get(uri) + self.expected_success(200, resp.status) + body = self.deserialize(body) + return service_client.ResponseBody(resp, body) + + def show_alarm_history(self, alarm_id): + uri = "%s/alarms/%s/history" % (self.uri_prefix, alarm_id) + resp, body = self.get(uri) + self.expected_success(200, resp.status) + body = self.deserialize(body) + return service_client.ResponseBodyList(resp, body) + + def delete_alarm(self, alarm_id): + uri = "%s/alarms/%s" % (self.uri_prefix, alarm_id) + resp, body = self.delete(uri) + self.expected_success(204, resp.status) + if body: + body = self.deserialize(body) + return service_client.ResponseBody(resp, body) + + def create_alarm(self, **kwargs): + uri = "%s/alarms" % self.uri_prefix + body = self.serialize(kwargs) + resp, body = self.post(uri, body) + self.expected_success(201, resp.status) + body = self.deserialize(body) + return service_client.ResponseBody(resp, body) + + def update_alarm(self, alarm_id, **kwargs): + uri = "%s/alarms/%s" % (self.uri_prefix, alarm_id) + body = self.serialize(kwargs) + resp, body = self.put(uri, body) + self.expected_success(200, resp.status) + body = self.deserialize(body) + return service_client.ResponseBody(resp, body) + + def show_alarm_state(self, alarm_id): + uri = "%s/alarms/%s/state" % (self.uri_prefix, alarm_id) + resp, body = self.get(uri) + self.expected_success(200, resp.status) + body = self.deserialize(body) + return service_client.ResponseBodyData(resp, body) + + def alarm_set_state(self, alarm_id, state): + uri = "%s/alarms/%s/state" % (self.uri_prefix, alarm_id) + body = self.serialize(state) + resp, body = self.put(uri, body) + self.expected_success(200, resp.status) + body = self.deserialize(body) + return service_client.ResponseBodyData(resp, body) diff --git a/tempest/services/telemetry/json/telemetry_client.py b/tempest/services/telemetry/json/telemetry_client.py index fc8951eed..05530b15d 100644 --- a/tempest/services/telemetry/json/telemetry_client.py +++ b/tempest/services/telemetry/json/telemetry_client.py @@ -72,10 +72,6 @@ class TelemetryClient(service_client.ServiceClient): uri = '%s/meters' % self.uri_prefix return self._helper_list(uri, query) - def list_alarms(self, query=None): - uri = '%s/alarms' % self.uri_prefix - return self._helper_list(uri, query) - def list_statistics(self, meter, period=None, query=None): uri = "%s/meters/%s/statistics" % (self.uri_prefix, meter) return self._helper_list(uri, query, period) @@ -94,56 +90,3 @@ class TelemetryClient(service_client.ServiceClient): self.expected_success(200, resp.status) body = self.deserialize(body) return service_client.ResponseBody(resp, body) - - def show_alarm(self, alarm_id): - uri = '%s/alarms/%s' % (self.uri_prefix, alarm_id) - resp, body = self.get(uri) - self.expected_success(200, resp.status) - body = self.deserialize(body) - return service_client.ResponseBody(resp, body) - - def delete_alarm(self, alarm_id): - uri = "%s/alarms/%s" % (self.uri_prefix, alarm_id) - resp, body = self.delete(uri) - self.expected_success(204, resp.status) - if body: - body = self.deserialize(body) - return service_client.ResponseBody(resp, body) - - def create_alarm(self, **kwargs): - uri = "%s/alarms" % self.uri_prefix - body = self.serialize(kwargs) - resp, body = self.post(uri, body) - self.expected_success(201, resp.status) - body = self.deserialize(body) - return service_client.ResponseBody(resp, body) - - def update_alarm(self, alarm_id, **kwargs): - uri = "%s/alarms/%s" % (self.uri_prefix, alarm_id) - body = self.serialize(kwargs) - resp, body = self.put(uri, body) - self.expected_success(200, resp.status) - body = self.deserialize(body) - return service_client.ResponseBody(resp, body) - - def show_alarm_state(self, alarm_id): - uri = "%s/alarms/%s/state" % (self.uri_prefix, alarm_id) - resp, body = self.get(uri) - self.expected_success(200, resp.status) - body = self.deserialize(body) - return service_client.ResponseBodyData(resp, body) - - def alarm_set_state(self, alarm_id, state): - uri = "%s/alarms/%s/state" % (self.uri_prefix, alarm_id) - body = self.serialize(state) - resp, body = self.put(uri, body) - self.expected_success(200, resp.status) - body = self.deserialize(body) - return service_client.ResponseBodyData(resp, body) - - def show_alarm_history(self, alarm_id): - uri = "%s/alarms/%s/history" % (self.uri_prefix, alarm_id) - resp, body = self.get(uri) - self.expected_success(200, resp.status) - body = self.deserialize(body) - return service_client.ResponseBodyList(resp, body) diff --git a/tempest/tests/common/test_service_clients.py b/tempest/tests/common/test_service_clients.py index 4225da84f..b26ba7d5b 100644 --- a/tempest/tests/common/test_service_clients.py +++ b/tempest/tests/common/test_service_clients.py @@ -46,6 +46,7 @@ from tempest.services.object_storage import account_client from tempest.services.object_storage import container_client from tempest.services.object_storage import object_client from tempest.services.orchestration.json import orchestration_client +from tempest.services.telemetry.json import alarming_client from tempest.services.telemetry.json import telemetry_client from tempest.services.volume.json.admin import volume_hosts_client from tempest.services.volume.json.admin import volume_quotas_client @@ -105,6 +106,7 @@ class TestServiceClient(base.TestCase): object_client.ObjectClient, orchestration_client.OrchestrationClient, telemetry_client.TelemetryClient, + alarming_client.AlarmingClient, qos_client.QosSpecsClient, volume_hosts_client.VolumeHostsClient, volume_quotas_client.VolumeQuotasClient, |