Remove Ceilometer tempest tests

Now Ceilometer and Aodh tempest plugins are implemented and all
tests and supported code is present in plugins.
-https://github.com/openstack/aodh/tree/master/aodh/tests/tempest
-https://github.com/openstack/ceilometer/tree/master/ceilometer/tests/tempest

NOTE- Need to keep config option 'CONF.service_available.ceilometer'
as it is being used in Congress tests in Kilo and Liberty branch and
Ceilometer tempest plugin is available since Mitaka.
If we remove that then, we will be breaking Congress gate for stable branches.

Change-Id: I0775bcc15dc9cbae6e075fe92f44b5f6c9b9d5d2
Depends-On: Ic0e6b72d8767d92cc63968c442c4ff65bb001cda
This commit is contained in:
ghanshyam 2016-04-13 15:49:22 +09:00
parent a66e40eb8e
commit e4796f8de4
20 changed files with 4 additions and 911 deletions

View File

@ -61,5 +61,3 @@ objects:
owner: javelin
file: /etc/hosts
swift_role: Member
telemetry: true

View File

@ -1,196 +0,0 @@
# 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.
import time
from oslo_utils import timeutils
from tempest.common import compute
from tempest.common.utils import data_utils
from tempest.common import waiters
from tempest import config
from tempest import exceptions
from tempest.lib import exceptions as lib_exc
import tempest.test
CONF = config.CONF
class BaseTelemetryTest(tempest.test.BaseTestCase):
"""Base test case class for all Telemetry API tests."""
credentials = ['primary']
@classmethod
def skip_checks(cls):
super(BaseTelemetryTest, cls).skip_checks()
if not CONF.service_available.ceilometer:
raise cls.skipException("Ceilometer support is required")
@classmethod
def setup_credentials(cls):
cls.set_network_resources()
super(BaseTelemetryTest, cls).setup_credentials()
@classmethod
def setup_clients(cls):
super(BaseTelemetryTest, cls).setup_clients()
cls.telemetry_client = cls.os.telemetry_client
cls.servers_client = cls.os.servers_client
cls.flavors_client = cls.os.flavors_client
cls.image_client = cls.os.image_client
cls.image_client_v2 = cls.os.image_client_v2
@classmethod
def resource_setup(cls):
super(BaseTelemetryTest, cls).resource_setup()
cls.nova_notifications = ['memory', 'vcpus', 'disk.root.size',
'disk.ephemeral.size']
cls.glance_notifications = ['image.size']
cls.glance_v2_notifications = ['image.download', 'image.serve']
cls.server_ids = []
cls.image_ids = []
@classmethod
def create_server(cls):
tenant_network = cls.get_tenant_network()
body, server = compute.create_test_server(
cls.os,
tenant_network=tenant_network,
name=data_utils.rand_name('ceilometer-instance'),
wait_until='ACTIVE')
cls.server_ids.append(body['id'])
return body
@classmethod
def create_image(cls, client, **kwargs):
body = client.create_image(name=data_utils.rand_name('image'),
container_format='bare',
disk_format='raw',
**kwargs)
# TODO(jswarren) Move ['image'] up to initial body value assignment
# once both v1 and v2 glance clients include the full response
# object.
if 'image' in body:
body = body['image']
cls.image_ids.append(body['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 wait_for_server_termination(cls, server_id):
waiters.wait_for_server_termination(cls.servers_client,
server_id)
@classmethod
def resource_cleanup(cls):
cls.cleanup_resources(cls.servers_client.delete_server, cls.server_ids)
cls.cleanup_resources(cls.wait_for_server_termination, cls.server_ids)
cls.cleanup_resources(cls.image_client.delete_image, cls.image_ids)
super(BaseTelemetryTest, cls).resource_cleanup()
def await_samples(self, metric, query):
"""This method is to wait for sample to add it to database.
There are long time delays when using Postgresql (or Mysql)
database as ceilometer backend
"""
timeout = CONF.compute.build_timeout
start = timeutils.utcnow()
while timeutils.delta_seconds(start, timeutils.utcnow()) < timeout:
body = self.telemetry_client.list_samples(metric, query)
if body:
return body
time.sleep(CONF.compute.build_interval)
raise exceptions.TimeoutException(
'Sample for metric:%s with query:%s has not been added to the '
'database within %d seconds' % (metric, query,
CONF.compute.build_timeout))
class BaseTelemetryAdminTest(BaseTelemetryTest):
"""Base test case class for admin Telemetry API tests."""
credentials = ['primary', 'admin']
@classmethod
def setup_clients(cls):
super(BaseTelemetryAdminTest, cls).setup_clients()
cls.telemetry_admin_client = cls.os_adm.telemetry_client
def await_events(self, query):
timeout = CONF.compute.build_timeout
start = timeutils.utcnow()
while timeutils.delta_seconds(start, timeutils.utcnow()) < timeout:
body = self.telemetry_admin_client.list_events(query)
if body:
return body
time.sleep(CONF.compute.build_interval)
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()

View File

@ -1,110 +0,0 @@
# 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 tempest.api.telemetry import base
from tempest.common.utils import data_utils
from tempest.lib import exceptions as lib_exc
from tempest import test
class TelemetryAlarmingAPITestJSON(base.BaseAlarmingTest):
@classmethod
def resource_setup(cls):
super(TelemetryAlarmingAPITestJSON, cls).resource_setup()
cls.rule = {'meter_name': 'cpu_util',
'comparison_operator': 'gt',
'threshold': 80.0,
'period': 70}
for i in range(2):
cls.create_alarm(threshold_rule=cls.rule)
@test.idempotent_id('1c918e06-210b-41eb-bd45-14676dd77cd6')
def test_alarm_list(self):
# 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]
missing_alarms = [a for a in self.alarm_ids if a not in fetched_ids]
self.assertEqual(0, len(missing_alarms),
"Failed to find the following created alarm(s)"
" in a fetched list: %s" %
', '.join(str(a) for a in missing_alarms))
@test.idempotent_id('1297b095-39c1-4e74-8a1f-4ae998cedd67')
def test_create_update_get_delete_alarm(self):
# Create an alarm
alarm_name = data_utils.rand_name('telemetry_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']
self.assertDictContainsSubset(self.rule, body['threshold_rule'])
# Update alarm with new rule and new name
new_rule = {'meter_name': 'cpu',
'comparison_operator': 'eq',
'threshold': 70.0,
'period': 60}
alarm_name_updated = data_utils.rand_name('telemetry-alarm-update')
body = self.alarming_client.update_alarm(
alarm_id,
threshold_rule=new_rule,
name=alarm_name_updated,
type='threshold')
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.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.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.alarming_client.delete_alarm(alarm_id)
self.assertRaises(lib_exc.NotFound,
self.alarming_client.show_alarm, alarm_id)
@test.idempotent_id('aca49486-70bb-4016-87e0-f6131374f741')
def test_set_get_alarm_state(self):
alarm_states = ['ok', 'alarm', 'insufficient data']
alarm = self.create_alarm(threshold_rule=self.rule)
# Set alarm state and verify
new_state =\
[elem for elem in alarm_states if elem != alarm['state']][0]
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.alarming_client.show_alarm_state(alarm['alarm_id'])
self.assertEqual(new_state, state.data)
@test.idempotent_id('08d7e45a-1344-4e5c-ba6f-f6cbb77f55b9')
def test_create_delete_alarm_with_combination_rule(self):
rule = {"alarm_ids": self.alarm_ids,
"operator": "or"}
# Verifies alarm create
alarm_name = data_utils.rand_name('combination_alarm')
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.alarming_client.delete_alarm(alarm_id)
self.assertRaises(lib_exc.NotFound,
self.alarming_client.show_alarm, alarm_id)

View File

@ -1,69 +0,0 @@
# Copyright 2015 GlobalLogic. 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 tempest.api.telemetry import base
from tempest.common.utils import data_utils
from tempest.lib import exceptions as lib_exc
from tempest import test
class TelemetryAlarmingNegativeTest(base.BaseAlarmingTest):
"""Negative tests for show_alarm, update_alarm, show_alarm_history tests
** show non-existent alarm
** show the deleted alarm
** delete deleted alarm
** update deleted alarm
"""
@test.attr(type=['negative'])
@test.idempotent_id('668743d5-08ad-4480-b2b8-15da34f81e7d')
def test_get_non_existent_alarm(self):
# get the non-existent alarm
non_existent_id = data_utils.rand_uuid()
self.assertRaises(lib_exc.NotFound, self.alarming_client.show_alarm,
non_existent_id)
@test.attr(type=['negative'])
@test.idempotent_id('ef45000d-0a72-4781-866d-4cb7bf2582ad')
def test_get_update_show_history_delete_deleted_alarm(self):
# get, update and delete the deleted alarm
alarm_name = data_utils.rand_name('telemetry_alarm')
rule = {'meter_name': 'cpu',
'comparison_operator': 'eq',
'threshold': 100.0,
'period': 90}
body = self.alarming_client.create_alarm(
name=alarm_name,
type='threshold',
threshold_rule=rule)
alarm_id = body['alarm_id']
self.alarming_client.delete_alarm(alarm_id)
# get the deleted alarm
self.assertRaises(lib_exc.NotFound, self.alarming_client.show_alarm,
alarm_id)
# update the deleted alarm
updated_alarm_name = data_utils.rand_name('telemetry_alarm_updated')
updated_rule = {'meter_name': 'cpu_new',
'comparison_operator': 'eq',
'threshold': 70,
'period': 50}
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.alarming_client.delete_alarm,
alarm_id)

View File

@ -1,84 +0,0 @@
# 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.
import testtools
from tempest.api.telemetry import base
from tempest import config
from tempest.lib import decorators
from tempest import test
CONF = config.CONF
class TelemetryNotificationAPITestJSON(base.BaseTelemetryTest):
@test.idempotent_id('d7f8c1c8-d470-4731-8604-315d3956caad')
@test.services('compute')
def test_check_nova_notification(self):
body = self.create_server()
query = ('resource', 'eq', body['id'])
for metric in self.nova_notifications:
self.await_samples(metric, query)
@test.attr(type="smoke")
@test.idempotent_id('04b10bfe-a5dc-47af-b22f-0460426bf498')
@test.services("image")
@testtools.skipIf(not CONF.image_feature_enabled.api_v1,
"Glance api v1 is disabled")
def test_check_glance_v1_notifications(self):
body = self.create_image(self.image_client, is_public=False)
self.image_client.update_image(body['id'], data='data')
query = 'resource', 'eq', body['id']
self.image_client.delete_image(body['id'])
for metric in self.glance_notifications:
self.await_samples(metric, query)
@test.attr(type="smoke")
@test.idempotent_id('c240457d-d943-439b-8aea-85e26d64fe8e')
@test.services("image")
@testtools.skipIf(not CONF.image_feature_enabled.api_v2,
"Glance api v2 is disabled")
def test_check_glance_v2_notifications(self):
body = self.create_image(self.image_client_v2, visibility='private')
self.image_client_v2.store_image_file(body['id'], "file")
self.image_client_v2.show_image_file(body['id'])
query = 'resource', 'eq', body['id']
for metric in self.glance_v2_notifications:
self.await_samples(metric, query)
class TelemetryNotificationAdminAPITestJSON(base.BaseTelemetryAdminTest):
@test.idempotent_id('29604198-8b45-4fc0-8af8-1cae4f94ebe9')
@test.services('compute')
@decorators.skip_because(bug='1480490')
def test_check_nova_notification_event_and_meter(self):
body = self.create_server()
if CONF.telemetry_feature_enabled.events:
query = ('instance_id', 'eq', body['id'])
self.await_events(query)
query = ('resource', 'eq', body['id'])
for metric in self.nova_notifications:
self.await_samples(metric, query)

View File

@ -138,9 +138,6 @@ 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.v1.json.admin.hosts_client import \
HostsClient as VolumeHostsClient
from tempest.services.volume.v1.json.admin.quotas_client import \
@ -324,20 +321,6 @@ class Manager(manager.Manager):
build_interval=CONF.network.build_interval,
build_timeout=CONF.network.build_timeout,
**self.default_params)
if CONF.service_available.ceilometer:
self.telemetry_client = TelemetryClient(
self.auth_provider,
CONF.telemetry.catalog_type,
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 = ImagesClient(
self.auth_provider,

View File

@ -33,7 +33,6 @@ CONF_PUB_ROUTER = None
CONF_TENANTS = None
CONF_USERS = None
IS_AODH = None
IS_CINDER = None
IS_GLANCE = None
IS_HEAT = None
@ -51,14 +50,12 @@ def init_conf():
global CONF_PUB_ROUTER
global CONF_TENANTS
global CONF_USERS
global IS_AODH
global IS_CINDER
global IS_GLANCE
global IS_HEAT
global IS_NEUTRON
global IS_NOVA
IS_AODH = CONF.service_available.aodh
IS_CINDER = CONF.service_available.cinder
IS_GLANCE = CONF.service_available.glance
IS_HEAT = CONF.service_available.heat
@ -706,32 +703,6 @@ class NetworkSubnetService(NetworkService):
self.data['subnets'] = subnets
# Telemetry services
class TelemetryAlarmService(BaseService):
def __init__(self, manager, **kwargs):
super(TelemetryAlarmService, self).__init__(kwargs)
self.client = manager.alarming_client
def list(self):
client = self.client
alarms = client.list_alarms()
LOG.debug("List count, %s Alarms" % len(alarms))
return alarms
def delete(self):
client = self.client
alarms = self.list()
for alarm in alarms:
try:
client.delete_alarm(alarm['id'])
except Exception:
LOG.exception("Delete Alarms exception.")
def dry_run(self):
alarms = self.list()
self.data['alarms'] = alarms
# begin global services
class FlavorService(BaseService):
def __init__(self, manager, **kwargs):
@ -976,8 +947,8 @@ class DomainService(BaseService):
def get_tenant_cleanup_services():
tenant_services = []
if IS_AODH:
tenant_services.append(TelemetryAlarmService)
# TODO(gmann): Tempest should provide some plugin hook for cleanup
# script extension to plugin tests also.
if IS_NOVA:
tenant_services.append(ServerService)
tenant_services.append(KeyPairService)

View File

@ -113,7 +113,6 @@ import unittest
import netaddr
from oslo_log import log as logging
from oslo_utils import timeutils
import six
import yaml
@ -138,8 +137,6 @@ from tempest.services.image.v2.json import images_client
from tempest.services.network.json import routers_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.v1.json import volumes_client
CONF = config.CONF
@ -244,18 +241,6 @@ class OSClient(object):
build_interval=CONF.image.build_interval,
build_timeout=CONF.image.build_timeout,
**default_params)
self.telemetry = telemetry_client.TelemetryClient(
_auth,
CONF.telemetry.catalog_type,
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,
@ -461,7 +446,6 @@ class JavelinCheck(unittest.TestCase):
self.check_objects()
self.check_servers()
self.check_volumes()
self.check_telemetry()
self.check_secgroups()
# validate neutron is enabled and ironic disabled:
@ -563,27 +547,6 @@ class JavelinCheck(unittest.TestCase):
found,
"Couldn't find expected secgroup %s" % secgroup['name'])
def check_telemetry(self):
"""Check that ceilometer provides a sane sample.
Confirm that there is more than one sample and that they have the
expected metadata.
If in check mode confirm that the oldest sample available is from
before the upgrade.
"""
if not self.res.get('telemetry'):
return
LOG.info("checking telemetry")
for server in self.res['servers']:
client = client_for_user(server['owner'])
body = client.telemetry.list_samples(
'instance',
query=('metadata.display_name', 'eq', server['name'])
)
self.assertTrue(len(body) >= 1, 'expecting at least one sample')
self._confirm_telemetry_sample(server, body[-1])
def check_volumes(self):
"""Check that the volumes are still there and attached."""
if not self.res.get('volumes'):
@ -602,26 +565,6 @@ class JavelinCheck(unittest.TestCase):
self.assertEqual(vol_body['id'], attachment['volume_id'])
self.assertEqual(server_id, attachment['server_id'])
def _confirm_telemetry_sample(self, server, sample):
"""Check this sample matches the expected resource metadata."""
# Confirm display_name
self.assertEqual(server['name'],
sample['resource_metadata']['display_name'])
# Confirm instance_type of flavor
flavor = sample['resource_metadata'].get(
'flavor.name',
sample['resource_metadata'].get('instance_type')
)
self.assertEqual(server['flavor'], flavor)
# Confirm the oldest sample was created before upgrade.
if OPTS.mode == 'check':
oldest_timestamp = timeutils.normalize_time(
timeutils.parse_isotime(sample['timestamp']))
self.assertTrue(
oldest_timestamp < JAVELIN_START,
'timestamp should come before start of second javelin run'
)
def check_networking(self):
"""Check that the networks are still there."""
for res_type in ('networks', 'subnets', 'routers'):

View File

@ -93,4 +93,3 @@ objects:
name: javelin1
owner: javelin
file: /etc/hosts
telemetry: true

View File

@ -272,8 +272,6 @@ def check_service_availability(os, update):
'object_storage': 'swift',
'compute': 'nova',
'orchestration': 'heat',
'metering': 'ceilometer',
'telemetry': 'ceilometer',
'data_processing': 'sahara',
'baremetal': 'ironic',
'identity': 'keystone',

View File

@ -892,50 +892,6 @@ OrchestrationGroup = [
]
telemetry_group = cfg.OptGroup(name='telemetry',
title='Telemetry Service Options')
TelemetryGroup = [
cfg.StrOpt('catalog_type',
default='metering',
help="Catalog type of the Telemetry service."),
cfg.StrOpt('endpoint_type',
default='publicURL',
choices=['public', 'admin', 'internal',
'publicURL', 'adminURL', 'internalURL'],
help="The endpoint type to use for the telemetry service."),
cfg.BoolOpt('too_slow_to_test',
default=True,
deprecated_for_removal=True,
help="This variable is used as flag to enable "
"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')
TelemetryFeaturesGroup = [
cfg.BoolOpt('events',
default=False,
help="Runs Ceilometer event-related tests"),
]
dashboard_group = cfg.OptGroup(name="dashboard",
title="Dashboard options")
@ -1080,12 +1036,6 @@ ServiceAvailableGroup = [
cfg.BoolOpt('heat',
default=False,
help="Whether or not Heat is expected to be available"),
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"),
@ -1231,9 +1181,6 @@ _opts = [
(object_storage_feature_group, ObjectStoreFeaturesGroup),
(database_group, DatabaseGroup),
(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),
@ -1302,8 +1249,6 @@ class TempestConfigPrivate(object):
'object-storage-feature-enabled']
self.database = _CONF.database
self.orchestration = _CONF.orchestration
self.telemetry = _CONF.telemetry
self.telemetry_feature_enabled = _CONF['telemetry-feature-enabled']
self.dashboard = _CONF.dashboard
self.data_processing = _CONF['data-processing']
self.data_processing_feature_enabled = _CONF[

View File

@ -19,8 +19,7 @@ import pep8
PYTHON_CLIENTS = ['cinder', 'glance', 'keystone', 'nova', 'swift', 'neutron',
'trove', 'ironic', 'savanna', 'heat', 'ceilometer',
'sahara']
'trove', 'ironic', 'savanna', 'heat', 'sahara']
PYTHON_CLIENT_RE = re.compile('import (%s)client' % '|'.join(PYTHON_CLIENTS))
TEST_DEFINITION = re.compile(r'^\s*def test.*')

View File

@ -1,6 +1,4 @@
./tempest/services/object_storage/object_client.py
./tempest/services/telemetry/json/alarming_client.py
./tempest/services/telemetry/json/telemetry_client.py
./tempest/services/volume/base/base_qos_client.py
./tempest/services/volume/base/base_backups_client.py
./tempest/services/baremetal/base.py

View File

@ -1,102 +0,0 @@
# Copyright 2014 Red Hat
#
# 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_log import log as logging
from tempest import config
from tempest.scenario import manager
from tempest import test
CONF = config.CONF
LOG = logging.getLogger(__name__)
# Loop for up to 120 seconds waiting on notifications
# NOTE(chdent): The choice of 120 seconds is fairly
# arbitrary: Long enough to give the notifications the
# chance to travel across a highly latent bus but not
# so long as to allow excessive latency to never be visible.
# TODO(chdent): Ideally this value would come from configuration.
NOTIFICATIONS_WAIT = 120
NOTIFICATIONS_SLEEP = 1
class TestObjectStorageTelemetry(manager.ObjectStorageScenarioTest):
"""Test that swift uses the ceilometer middleware.
* create container.
* upload a file to the created container.
* retrieve the file from the created container.
* wait for notifications from ceilometer.
"""
@classmethod
def skip_checks(cls):
super(TestObjectStorageTelemetry, cls).skip_checks()
if not CONF.service_available.ceilometer:
skip_msg = ("%s skipped as ceilometer is not available" %
cls.__name__)
raise cls.skipException(skip_msg)
@classmethod
def setup_clients(cls):
super(TestObjectStorageTelemetry, cls).setup_clients()
cls.telemetry_client = cls.os_operator.telemetry_client
def _confirm_notifications(self, container_name, obj_name):
# NOTE: Loop seeking for appropriate notifications about the containers
# and objects sent to swift.
def _check_samples():
# NOTE: Return True only if we have notifications about some
# containers and some objects and the notifications are about
# the expected containers and objects.
# Otherwise returning False will case _check_samples to be
# called again.
results = self.telemetry_client.list_samples(
'storage.objects.incoming.bytes')
LOG.debug('got samples %s', results)
# Extract container info from samples.
containers, objects = [], []
for sample in results:
meta = sample['resource_metadata']
if meta.get('container') and meta['container'] != 'None':
containers.append(meta['container'])
elif (meta.get('target.metadata:container') and
meta['target.metadata:container'] != 'None'):
containers.append(meta['target.metadata:container'])
if meta.get('object') and meta['object'] != 'None':
objects.append(meta['object'])
elif (meta.get('target.metadata:object') and
meta['target.metadata:object'] != 'None'):
objects.append(meta['target.metadata:object'])
return (container_name in containers and obj_name in objects)
self.assertTrue(test.call_until_true(_check_samples,
NOTIFICATIONS_WAIT,
NOTIFICATIONS_SLEEP),
'Correct notifications were not received after '
'%s seconds.' % NOTIFICATIONS_WAIT)
@test.idempotent_id('6d6b88e5-3e38-41bc-b34a-79f713a6cb84')
@test.services('object_storage', 'telemetry')
def test_swift_middleware_notifies(self):
container_name = self.create_container()
obj_name, _ = self.upload_object_to_container(container_name)
self._confirm_notifications(container_name, obj_name)

View File

@ -1,98 +0,0 @@
# 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.lib.common import rest_client
class AlarmingClient(rest_client.RestClient):
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 rest_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 rest_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 rest_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 rest_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 rest_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 rest_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 rest_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 rest_client.ResponseBodyData(resp, body)

View File

@ -1,81 +0,0 @@
# 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.lib.common import rest_client
class TelemetryClient(rest_client.RestClient):
version = '2'
uri_prefix = "v2"
def deserialize(self, body):
return json.loads(body.replace("\n", ""))
def serialize(self, body):
return json.dumps(body)
def create_sample(self, meter_name, sample_list):
uri = "%s/meters/%s" % (self.uri_prefix, meter_name)
body = self.serialize(sample_list)
resp, body = self.post(uri, body)
self.expected_success(200, resp.status)
body = self.deserialize(body)
return rest_client.ResponseBody(resp, body)
def _helper_list(self, uri, query=None, period=None):
uri_dict = {}
if query:
uri_dict = {'q.field': query[0],
'q.op': query[1],
'q.value': query[2]}
if period:
uri_dict['period'] = period
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 rest_client.ResponseBodyList(resp, body)
def list_resources(self, query=None):
uri = '%s/resources' % self.uri_prefix
return self._helper_list(uri, query)
def list_meters(self, query=None):
uri = '%s/meters' % 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)
def list_samples(self, meter_id, query=None):
uri = '%s/meters/%s' % (self.uri_prefix, meter_id)
return self._helper_list(uri, query)
def list_events(self, query=None):
uri = '%s/events' % self.uri_prefix
return self._helper_list(uri, query)
def show_resource(self, resource_id):
uri = '%s/resources/%s' % (self.uri_prefix, resource_id)
resp, body = self.get(uri)
self.expected_success(200, resp.status)
body = self.deserialize(body)
return rest_client.ResponseBody(resp, body)

View File

@ -78,7 +78,6 @@ def get_service_list():
'identity': True,
'object_storage': CONF.service_available.swift,
'dashboard': CONF.service_available.horizon,
'telemetry': CONF.service_available.ceilometer,
'data_processing': CONF.service_available.sahara,
'database': CONF.service_available.trove
}
@ -94,7 +93,7 @@ def services(*args):
def decorator(f):
services = ['compute', 'image', 'baremetal', 'volume', 'orchestration',
'network', 'identity', 'object_storage', 'dashboard',
'telemetry', 'data_processing', 'database']
'data_processing', 'database']
for service in args:
if service not in services:
raise exceptions.InvalidServiceTag('%s is not a valid '