From 62008d4e5bf688024c0be575ee37df20b82bb722 Mon Sep 17 00:00:00 2001 From: Julien Danjou Date: Mon, 15 Sep 2014 12:07:04 +0200 Subject: [PATCH] Switch to a custom NotImplementedError Some drivers/modules might raise NotImplementedError whereas we would expect things to work. Skipping test when such an error is raised would be a bad idea, we would know the test failed. So let's switch to a custom NotImplementedError and let's skip test only if this one is raised. Closes-Bug: #1369556 Change-Id: Ie88a281787218f9aba13b6e662eb4d49d3e685d0 --- ceilometer/__init__.py | 22 ++++++++++++++ ceilometer/alarm/storage/base.py | 21 ++++++------- ceilometer/alarm/storage/impl_hbase.py | 6 ++-- ceilometer/alarm/storage/impl_sqlalchemy.py | 3 +- ceilometer/alarm/storage/pymongo_base.py | 3 +- ceilometer/api/controllers/v2.py | 5 ++-- ceilometer/compute/pollsters/cpu.py | 6 ++-- ceilometer/compute/pollsters/disk.py | 5 ++-- ceilometer/compute/pollsters/memory.py | 4 +-- ceilometer/compute/pollsters/net.py | 3 +- ceilometer/compute/virt/inspector.py | 17 ++++++----- ceilometer/event/endpoint.py | 3 +- ceilometer/storage/base.py | 30 +++++++++++-------- ceilometer/storage/hbase/inmemory.py | 20 ++++++++----- ceilometer/storage/impl_db2.py | 9 ++++-- ceilometer/storage/impl_hbase.py | 11 ++++--- ceilometer/storage/impl_mongodb.py | 11 ++++--- ceilometer/storage/impl_sqlalchemy.py | 21 +++++++------ ceilometer/storage/pymongo_base.py | 3 +- ceilometer/storage/sqlalchemy/utils.py | 5 ++-- ceilometer/tests/base.py | 8 ++--- ceilometer/tests/event/test_endpoint.py | 4 ++- .../tests/storage/test_storage_scenarios.py | 3 +- 23 files changed, 140 insertions(+), 83 deletions(-) diff --git a/ceilometer/__init__.py b/ceilometer/__init__.py index e69de29bb..51a51c31d 100644 --- a/ceilometer/__init__.py +++ b/ceilometer/__init__.py @@ -0,0 +1,22 @@ +# Copyright 2014 eNovance +# +# Authors: Julien Danjou +# +# 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. + + +class NotImplementedError(NotImplementedError): + # FIXME(jd) This is used by WSME to return a correct HTTP code. We should + # not expose it here but wrap our methods in the API to convert it to a + # proper HTTP error. + code = 501 diff --git a/ceilometer/alarm/storage/base.py b/ceilometer/alarm/storage/base.py index 06a50af3e..1bf8d9810 100644 --- a/ceilometer/alarm/storage/base.py +++ b/ceilometer/alarm/storage/base.py @@ -17,6 +17,7 @@ # under the License. """Base classes for storage engines """ +import ceilometer class Connection(object): @@ -46,7 +47,7 @@ class Connection(object): def get_alarms(name=None, user=None, state=None, meter=None, project=None, enabled=None, alarm_id=None, pagination=None): """Yields a lists of alarms that match filters.""" - raise NotImplementedError('Alarms not implemented') + raise ceilometer.NotImplementedError('Alarms not implemented') @staticmethod def create_alarm(alarm): @@ -54,17 +55,17 @@ class Connection(object): :param alarm: The alarm to create. """ - raise NotImplementedError('Alarms not implemented') + raise ceilometer.NotImplementedError('Alarms not implemented') @staticmethod def update_alarm(alarm): """Update alarm.""" - raise NotImplementedError('Alarms not implemented') + raise ceilometer.NotImplementedError('Alarms not implemented') @staticmethod def delete_alarm(alarm_id): """Delete an alarm.""" - raise NotImplementedError('Alarms not implemented') + raise ceilometer.NotImplementedError('Alarms not implemented') @staticmethod def get_alarm_changes(alarm_id, on_behalf_of, @@ -94,12 +95,12 @@ class Connection(object): :param end_timestamp: Optional modified timestamp end range :param end_timestamp_op: Optional timestamp end range operation """ - raise NotImplementedError('Alarm history not implemented') + raise ceilometer.NotImplementedError('Alarm history not implemented') @staticmethod def record_alarm_change(alarm_change): """Record alarm change event.""" - raise NotImplementedError('Alarm history not implemented') + raise ceilometer.NotImplementedError('Alarm history not implemented') @staticmethod def clear(): @@ -114,8 +115,8 @@ class Connection(object): :param limit: Maximum number of results to return. """ - raise NotImplementedError('Complex query for alarms ' - 'is not implemented.') + raise ceilometer.NotImplementedError('Complex query for alarms ' + 'is not implemented.') @staticmethod def query_alarm_history(filter_expr=None, orderby=None, limit=None): @@ -126,8 +127,8 @@ class Connection(object): :param limit: Maximum number of results to return. """ - raise NotImplementedError('Complex query for alarms ' - 'history is not implemented.') + raise ceilometer.NotImplementedError('Complex query for alarms ' + 'history is not implemented.') @classmethod def get_capabilities(cls): diff --git a/ceilometer/alarm/storage/impl_hbase.py b/ceilometer/alarm/storage/impl_hbase.py index d64409575..27311c661 100644 --- a/ceilometer/alarm/storage/impl_hbase.py +++ b/ceilometer/alarm/storage/impl_hbase.py @@ -19,6 +19,7 @@ import happybase from oslo.utils import netutils from six.moves.urllib import parse as urlparse +import ceilometer from ceilometer.alarm.storage import base from ceilometer.alarm.storage import models from ceilometer.openstack.common.gettextutils import _ @@ -178,9 +179,10 @@ class Connection(base.Connection): project=None, enabled=None, alarm_id=None, pagination=None): if pagination: - raise NotImplementedError('Pagination not implemented') + raise ceilometer.NotImplementedError('Pagination not implemented') if meter: - raise NotImplementedError('Filter by meter not implemented') + raise ceilometer.NotImplementedError( + 'Filter by meter not implemented') q = hbase_utils.make_query(alarm_id=alarm_id, name=name, enabled=enabled, user_id=user, diff --git a/ceilometer/alarm/storage/impl_sqlalchemy.py b/ceilometer/alarm/storage/impl_sqlalchemy.py index e0cc6c9ce..6e8f84776 100644 --- a/ceilometer/alarm/storage/impl_sqlalchemy.py +++ b/ceilometer/alarm/storage/impl_sqlalchemy.py @@ -24,6 +24,7 @@ from oslo.db.sqlalchemy import migration from oslo.db.sqlalchemy import session as db_session from sqlalchemy import desc +import ceilometer from ceilometer.alarm.storage import base from ceilometer.alarm.storage import models as alarm_api_models from ceilometer.openstack.common import log @@ -153,7 +154,7 @@ class Connection(base.Connection): """ if pagination: - raise NotImplementedError('Pagination not implemented') + raise ceilometer.NotImplementedError('Pagination not implemented') session = self._engine_facade.get_session() query = session.query(models.Alarm) diff --git a/ceilometer/alarm/storage/pymongo_base.py b/ceilometer/alarm/storage/pymongo_base.py index ef469ff2f..b012dd1e1 100644 --- a/ceilometer/alarm/storage/pymongo_base.py +++ b/ceilometer/alarm/storage/pymongo_base.py @@ -21,6 +21,7 @@ import pymongo +import ceilometer from ceilometer.alarm.storage import base from ceilometer.alarm.storage import models from ceilometer.openstack.common import log @@ -92,7 +93,7 @@ class Connection(base.Connection): :param pagination: Optional pagination query. """ if pagination: - raise NotImplementedError('Pagination not implemented') + raise ceilometer.NotImplementedError('Pagination not implemented') q = {} if user is not None: diff --git a/ceilometer/api/controllers/v2.py b/ceilometer/api/controllers/v2.py index a00b5abd9..1d78c376c 100644 --- a/ceilometer/api/controllers/v2.py +++ b/ceilometer/api/controllers/v2.py @@ -47,6 +47,7 @@ import wsme from wsme import types as wtypes import wsmeext.pecan as wsme_pecan +import ceilometer from ceilometer.alarm import service as alarm_service from ceilometer.alarm.storage import models as alarm_models from ceilometer.api import acl @@ -1990,7 +1991,7 @@ class AlarmController(rest.RestController): try: self.conn.record_alarm_change(payload) - except NotImplementedError: + except ceilometer.NotImplementedError: pass # Revert to the pre-json'ed details ... @@ -2146,7 +2147,7 @@ class AlarmsController(rest.RestController): try: conn.record_alarm_change(payload) - except NotImplementedError: + except ceilometer.NotImplementedError: pass # Revert to the pre-json'ed details ... diff --git a/ceilometer/compute/pollsters/cpu.py b/ceilometer/compute/pollsters/cpu.py index 6b7a06acb..f14620917 100644 --- a/ceilometer/compute/pollsters/cpu.py +++ b/ceilometer/compute/pollsters/cpu.py @@ -16,7 +16,7 @@ # 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 ceilometer from ceilometer.compute import plugin from ceilometer.compute.pollsters import util from ceilometer.compute.virt import inspector as virt_inspector @@ -50,7 +50,7 @@ class CPUPollster(plugin.ComputePollster): except virt_inspector.InstanceNotFoundException as err: # Instance was deleted while getting samples. Ignore it. LOG.debug(_('Exception while getting samples %s'), err) - except NotImplementedError: + except ceilometer.NotImplementedError: # Selected inspector does not implement this pollster. LOG.debug(_('Obtaining CPU time is not implemented for %s' ), manager.inspector.__class__.__name__) @@ -81,7 +81,7 @@ class CPUUtilPollster(plugin.ComputePollster): except virt_inspector.InstanceNotFoundException as err: # Instance was deleted while getting samples. Ignore it. LOG.debug(_('Exception while getting samples %s'), err) - except NotImplementedError: + except ceilometer.NotImplementedError: # Selected inspector does not implement this pollster. LOG.debug(_('Obtaining CPU Util is not implemented for %s'), manager.inspector.__class__.__name__) diff --git a/ceilometer/compute/pollsters/disk.py b/ceilometer/compute/pollsters/disk.py index aac0f388e..c54f3afa3 100644 --- a/ceilometer/compute/pollsters/disk.py +++ b/ceilometer/compute/pollsters/disk.py @@ -23,6 +23,7 @@ import collections import six +import ceilometer from ceilometer.compute import plugin from ceilometer.compute.pollsters import util from ceilometer.compute.virt import inspector as virt_inspector @@ -119,7 +120,7 @@ class _Base(plugin.ComputePollster): except virt_inspector.InstanceNotFoundException as err: # Instance was deleted while getting samples. Ignore it. LOG.debug(_('Exception while getting samples %s'), err) - except NotImplementedError: + except ceilometer.NotImplementedError: # Selected inspector does not implement this pollster. LOG.debug(_('%(inspector)s does not provide data for ' ' %(pollster)s'), @@ -324,7 +325,7 @@ class _DiskRatesPollsterBase(plugin.ComputePollster): except virt_inspector.InstanceNotFoundException as err: # Instance was deleted while getting samples. Ignore it. LOG.debug(_('Exception while getting samples %s'), err) - except NotImplementedError: + except ceilometer.NotImplementedError: # Selected inspector does not implement this pollster. LOG.debug(_('%(inspector)s does not provide data for ' ' %(pollster)s'), diff --git a/ceilometer/compute/pollsters/memory.py b/ceilometer/compute/pollsters/memory.py index 547e00399..f8d8001e9 100644 --- a/ceilometer/compute/pollsters/memory.py +++ b/ceilometer/compute/pollsters/memory.py @@ -12,7 +12,7 @@ # 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 ceilometer from ceilometer.compute import plugin from ceilometer.compute.pollsters import util from ceilometer.compute.virt import inspector as virt_inspector @@ -45,7 +45,7 @@ class MemoryUsagePollster(plugin.ComputePollster): except virt_inspector.InstanceNotFoundException as err: # Instance was deleted while getting samples. Ignore it. LOG.debug(_('Exception while getting samples %s'), err) - except NotImplementedError: + except ceilometer.NotImplementedError: # Selected inspector does not implement this pollster. LOG.debug(_('Obtaining Memory Usage is not implemented for %s' ), manager.inspector.__class__.__name__) diff --git a/ceilometer/compute/pollsters/net.py b/ceilometer/compute/pollsters/net.py index ba56ad923..00fb40d9e 100644 --- a/ceilometer/compute/pollsters/net.py +++ b/ceilometer/compute/pollsters/net.py @@ -21,6 +21,7 @@ import copy from oslo.utils import timeutils +import ceilometer from ceilometer.compute import plugin from ceilometer.compute.pollsters import util from ceilometer.compute.virt import inspector as virt_inspector @@ -104,7 +105,7 @@ class _Base(plugin.ComputePollster): except virt_inspector.InstanceNotFoundException as err: # Instance was deleted while getting samples. Ignore it. LOG.debug(_('Exception while getting samples %s'), err) - except NotImplementedError: + except ceilometer.NotImplementedError: # Selected inspector does not implement this pollster. LOG.debug(_('%(inspector)s does not provide data for ' ' %(pollster)s'), diff --git a/ceilometer/compute/virt/inspector.py b/ceilometer/compute/virt/inspector.py index 455a15521..b266ef427 100644 --- a/ceilometer/compute/virt/inspector.py +++ b/ceilometer/compute/virt/inspector.py @@ -22,6 +22,7 @@ import collections from oslo.config import cfg from stevedore import driver +import ceilometer from ceilometer.openstack.common.gettextutils import _ from ceilometer.openstack.common import log @@ -148,7 +149,7 @@ class Inspector(object): def inspect_instances(self): """List the instances on the current host.""" - raise NotImplementedError() + raise ceilometer.NotImplementedError def inspect_cpus(self, instance_name): """Inspect the CPU statistics for an instance. @@ -156,7 +157,7 @@ class Inspector(object): :param instance_name: the name of the target instance :return: the number of CPUs and cumulative CPU time """ - raise NotImplementedError() + raise ceilometer.NotImplementedError def inspect_cpu_util(self, instance, duration=None): """Inspect the CPU Utilization (%) for an instance. @@ -166,7 +167,7 @@ class Inspector(object): inspected :return: the percentage of CPU utilization """ - raise NotImplementedError() + raise ceilometer.NotImplementedError def inspect_vnics(self, instance_name): """Inspect the vNIC statistics for an instance. @@ -175,7 +176,7 @@ class Inspector(object): :return: for each vNIC, the number of bytes & packets received and transmitted """ - raise NotImplementedError() + raise ceilometer.NotImplementedError def inspect_vnic_rates(self, instance, duration=None): """Inspect the vNIC rate statistics for an instance. @@ -186,7 +187,7 @@ class Inspector(object): :return: for each vNIC, the rate of bytes & packets received and transmitted """ - raise NotImplementedError() + raise ceilometer.NotImplementedError def inspect_disks(self, instance_name): """Inspect the disk statistics for an instance. @@ -195,7 +196,7 @@ class Inspector(object): :return: for each disk, the number of bytes & operations read and written, and the error count """ - raise NotImplementedError() + raise ceilometer.NotImplementedError def inspect_memory_usage(self, instance, duration=None): """Inspect the memory usage statistics for an instance. @@ -205,7 +206,7 @@ class Inspector(object): inspected :return: the amount of memory used """ - raise NotImplementedError() + raise ceilometer.NotImplementedError def inspect_disk_rates(self, instance, duration=None): """Inspect the disk statistics as rates for an instance. @@ -216,7 +217,7 @@ class Inspector(object): :return: for each disk, the number of bytes & operations read and written per second, with the error count """ - raise NotImplementedError() + raise ceilometer.NotImplementedError def get_hypervisor_inspector(): diff --git a/ceilometer/event/endpoint.py b/ceilometer/event/endpoint.py index fa05c8a1f..fc22775b0 100644 --- a/ceilometer/event/endpoint.py +++ b/ceilometer/event/endpoint.py @@ -21,6 +21,7 @@ from oslo.config import cfg import oslo.messaging from stevedore import extension +import ceilometer from ceilometer import dispatcher from ceilometer.event import converter as event_converter from ceilometer import messaging @@ -66,7 +67,7 @@ class EventsNotificationEndpoint(object): try: problem_events.extend( dispatcher_ext.obj.record_events(event)) - except NotImplementedError: + except ceilometer.NotImplementedError: LOG.warn(_('Event is not implemented with the storage' ' backend')) if models.Event.UNKNOWN_PROBLEM in [x[0] for x in problem_events]: diff --git a/ceilometer/storage/base.py b/ceilometer/storage/base.py index 8fecd5dc3..7ad80f0f2 100644 --- a/ceilometer/storage/base.py +++ b/ceilometer/storage/base.py @@ -25,6 +25,8 @@ from oslo.utils import timeutils import six from six import moves +import ceilometer + def iter_period(start, end, period): """Split a time from start to end in periods of a number of seconds. @@ -188,7 +190,8 @@ class Connection(object): All timestamps must be naive utc datetime object. """ - raise NotImplementedError('Projects not implemented') + raise ceilometer.NotImplementedError( + 'Recording metering data is not implemented') @staticmethod def clear_expired_metering_data(ttl): @@ -198,7 +201,8 @@ class Connection(object): :param ttl: Number of seconds to keep records for. """ - raise NotImplementedError('Clearing samples not implemented') + raise ceilometer.NotImplementedError( + 'Clearing samples not implemented') @staticmethod def get_resources(user=None, project=None, source=None, @@ -219,7 +223,7 @@ class Connection(object): :param resource: Optional resource filter. :param pagination: Optional pagination query. """ - raise NotImplementedError('Resources not implemented') + raise ceilometer.NotImplementedError('Resources not implemented') @staticmethod def get_meters(user=None, project=None, resource=None, source=None, @@ -234,7 +238,7 @@ class Connection(object): :param metaquery: Optional dict with metadata to match on. :param pagination: Optional pagination query. """ - raise NotImplementedError('Meters not implemented') + raise ceilometer.NotImplementedError('Meters not implemented') @staticmethod def get_samples(sample_filter, limit=None): @@ -243,7 +247,7 @@ class Connection(object): :param sample_filter: Filter. :param limit: Maximum number of results to return. """ - raise NotImplementedError('Samples not implemented') + raise ceilometer.NotImplementedError('Samples not implemented') @staticmethod def get_meter_statistics(sample_filter, period=None, groupby=None, @@ -252,7 +256,7 @@ class Connection(object): The filter must have a meter value set. """ - raise NotImplementedError('Statistics not implemented') + raise ceilometer.NotImplementedError('Statistics not implemented') @staticmethod def clear(): @@ -264,17 +268,17 @@ class Connection(object): :param events: a list of model.Event objects. """ - raise NotImplementedError('Events not implemented.') + raise ceilometer.NotImplementedError('Events not implemented.') @staticmethod def get_events(event_filter): """Return an iterable of model.Event objects.""" - raise NotImplementedError('Events not implemented.') + raise ceilometer.NotImplementedError('Events not implemented.') @staticmethod def get_event_types(): """Return all event types as an iterable of strings.""" - raise NotImplementedError('Events not implemented.') + raise ceilometer.NotImplementedError('Events not implemented.') @staticmethod def get_trait_types(event_type): @@ -284,7 +288,7 @@ class Connection(object): returned. :param event_type: the type of the Event """ - raise NotImplementedError('Events not implemented.') + raise ceilometer.NotImplementedError('Events not implemented.') @staticmethod def get_traits(event_type, trait_type=None): @@ -295,7 +299,7 @@ class Connection(object): :param trait_type: the name of the Trait to filter by """ - raise NotImplementedError('Events not implemented.') + raise ceilometer.NotImplementedError('Events not implemented.') @staticmethod def query_samples(filter_expr=None, orderby=None, limit=None): @@ -306,8 +310,8 @@ class Connection(object): :param limit: Maximum number of results to return. """ - raise NotImplementedError('Complex query for samples ' - 'is not implemented.') + raise ceilometer.NotImplementedError('Complex query for samples ' + 'is not implemented.') @classmethod def get_capabilities(cls): diff --git a/ceilometer/storage/hbase/inmemory.py b/ceilometer/storage/hbase/inmemory.py index 3065078f6..abe7664fb 100644 --- a/ceilometer/storage/hbase/inmemory.py +++ b/ceilometer/storage/hbase/inmemory.py @@ -18,6 +18,7 @@ import copy import re import six +import ceilometer from ceilometer.openstack.common.gettextutils import _ from ceilometer.openstack.common import log @@ -111,8 +112,9 @@ class MTable(object): # in case of multiple filters rows = m(fargs, rows) else: - raise NotImplementedError("%s filter is not implemented, " - "you may want to add it!") + raise ceilometer.NotImplementedError( + "%s filter is not implemented, " + "you may want to add it!") for k in sorted(rows)[:limit]: yield k, rows[k] @@ -195,9 +197,10 @@ class MTable(object): if g == row: r[row] = data else: - raise NotImplementedError("In-memory " - "RowFilter doesn't support " - "the %s operation yet" % op) + raise ceilometer.NotImplementedError( + "In-memory " + "RowFilter doesn't support " + "the %s operation yet" % op) except AttributeError: pass return r @@ -226,9 +229,10 @@ class MTable(object): (op == '<' and key < column)): r_data[key] = data[key] else: - raise NotImplementedError("In-memory QualifierFilter " - "doesn't support the %s " - "operation yet" % op) + raise ceilometer.NotImplementedError( + "In-memory QualifierFilter " + "doesn't support the %s " + "operation yet" % op) if r_data: r[row] = r_data return r diff --git a/ceilometer/storage/impl_db2.py b/ceilometer/storage/impl_db2.py index 899b5df05..1b1e51274 100644 --- a/ceilometer/storage/impl_db2.py +++ b/ceilometer/storage/impl_db2.py @@ -32,6 +32,7 @@ from oslo.utils import timeutils import pymongo import six +import ceilometer from ceilometer.openstack.common import log from ceilometer import storage from ceilometer.storage import base @@ -252,7 +253,7 @@ class Connection(pymongo_base.Connection): :param pagination: Optional pagination query. """ if pagination: - raise NotImplementedError('Pagination not implemented') + raise ceilometer.NotImplementedError('Pagination not implemented') metaquery = metaquery or {} @@ -313,10 +314,12 @@ class Connection(pymongo_base.Connection): if (groupby and set(groupby) - set(['user_id', 'project_id', 'resource_id', 'source'])): - raise NotImplementedError("Unable to group by these fields") + raise ceilometer.NotImplementedError( + "Unable to group by these fields") if aggregate: - raise NotImplementedError('Selectable aggregates not implemented') + raise ceilometer.NotImplementedError( + 'Selectable aggregates not implemented') q = pymongo_utils.make_query_from_filter(sample_filter) diff --git a/ceilometer/storage/impl_hbase.py b/ceilometer/storage/impl_hbase.py index fe483641e..3899f4825 100644 --- a/ceilometer/storage/impl_hbase.py +++ b/ceilometer/storage/impl_hbase.py @@ -22,6 +22,7 @@ from oslo.utils import netutils from oslo.utils import timeutils from six.moves.urllib import parse as urlparse +import ceilometer from ceilometer.openstack.common.gettextutils import _ from ceilometer.openstack.common import log from ceilometer.storage import base @@ -276,7 +277,7 @@ class Connection(base.Connection): :param pagination: Optional pagination query. """ if pagination: - raise NotImplementedError('Pagination not implemented') + raise ceilometer.NotImplementedError('Pagination not implemented') q = hbase_utils.make_query(metaquery=metaquery, user_id=user, project_id=project, @@ -330,7 +331,8 @@ class Connection(base.Connection): metaquery = metaquery or {} if pagination: - raise NotImplementedError(_('Pagination not implemented')) + raise ceilometer.NotImplementedError( + _('Pagination not implemented')) with self.conn_pool.connection() as conn: resource_table = conn.table(self.RESOURCE_TABLE) q = hbase_utils.make_query(metaquery=metaquery, user_id=user, @@ -423,10 +425,11 @@ class Connection(base.Connection): because of all the Thrift traffic it is going to create. """ if groupby: - raise NotImplementedError("Group by not implemented.") + raise ceilometer.NotImplementedError("Group by not implemented.") if aggregate: - raise NotImplementedError('Selectable aggregates not implemented') + raise ceilometer.NotImplementedError( + 'Selectable aggregates not implemented') with self.conn_pool.connection() as conn: meter_table = conn.table(self.METER_TABLE) diff --git a/ceilometer/storage/impl_mongodb.py b/ceilometer/storage/impl_mongodb.py index 2b432767e..b9ce7a968 100644 --- a/ceilometer/storage/impl_mongodb.py +++ b/ceilometer/storage/impl_mongodb.py @@ -34,6 +34,7 @@ from oslo.utils import timeutils import pymongo import six +import ceilometer from ceilometer.openstack.common import log from ceilometer import storage from ceilometer.storage import base @@ -791,7 +792,7 @@ class Connection(pymongo_base.Connection): :param pagination: Optional pagination query. """ if pagination: - raise NotImplementedError('Pagination not implemented') + raise ceilometer.NotImplementedError('Pagination not implemented') metaquery = metaquery or {} @@ -837,8 +838,9 @@ class Connection(pymongo_base.Connection): params = dict(aggregate_param=a.param) fragments += (fragment_map[a.func] % params) else: - raise NotImplementedError('Selectable aggregate function %s' - ' is not supported' % a.func) + raise ceilometer.NotImplementedError( + 'Selectable aggregate function %s' + ' is not supported' % a.func) return fragments @@ -852,7 +854,8 @@ class Connection(pymongo_base.Connection): if (groupby and set(groupby) - set(['user_id', 'project_id', 'resource_id', 'source'])): - raise NotImplementedError("Unable to group by these fields") + raise ceilometer.NotImplementedError( + "Unable to group by these fields") q = pymongo_utils.make_query_from_filter(sample_filter) diff --git a/ceilometer/storage/impl_sqlalchemy.py b/ceilometer/storage/impl_sqlalchemy.py index f4d7de023..a34a5235f 100644 --- a/ceilometer/storage/impl_sqlalchemy.py +++ b/ceilometer/storage/impl_sqlalchemy.py @@ -34,6 +34,7 @@ from sqlalchemy import distinct from sqlalchemy import func from sqlalchemy.orm import aliased +import ceilometer from ceilometer.openstack.common.gettextutils import _ from ceilometer.openstack.common import jsonutils from ceilometer.openstack.common import log @@ -114,9 +115,10 @@ def apply_metaquery_filter(session, query, metaquery): try: _model = sql_utils.META_TYPE_MAP[type(value)] except KeyError: - raise NotImplementedError('Query on %(key)s is of %(value)s ' - 'type and is not supported' % - {"key": k, "value": type(value)}) + raise ceilometer.NotImplementedError( + 'Query on %(key)s is of %(value)s ' + 'type and is not supported' % + {"key": k, "value": type(value)}) else: meta_alias = aliased(_model) on_clause = and_(models.Resource.internal_id == meta_alias.id, @@ -390,7 +392,7 @@ class Connection(base.Connection): :param pagination: Optional pagination query. """ if pagination: - raise NotImplementedError('Pagination not implemented') + raise ceilometer.NotImplementedError('Pagination not implemented') s_filter = storage.SampleFilter(user=user, project=project, @@ -457,7 +459,7 @@ class Connection(base.Connection): """ if pagination: - raise NotImplementedError('Pagination not implemented') + raise ceilometer.NotImplementedError('Pagination not implemented') s_filter = storage.SampleFilter(user=user, project=project, @@ -590,8 +592,9 @@ class Connection(base.Connection): compute = PARAMETERIZED_AGGREGATES['compute'][a.func] functions.append(compute(a.param)) else: - raise NotImplementedError('Selectable aggregate function %s' - ' is not supported' % a.func) + raise ceilometer.NotImplementedError( + 'Selectable aggregate function %s' + ' is not supported' % a.func) return functions @@ -666,8 +669,8 @@ class Connection(base.Connection): if groupby: for group in groupby: if group not in ['user_id', 'project_id', 'resource_id']: - raise NotImplementedError('Unable to group by ' - 'these fields') + raise ceilometer.NotImplementedError('Unable to group by ' + 'these fields') if not period: for res in self._make_stats_query(sample_filter, diff --git a/ceilometer/storage/pymongo_base.py b/ceilometer/storage/pymongo_base.py index b40d32d2e..f6929a453 100644 --- a/ceilometer/storage/pymongo_base.py +++ b/ceilometer/storage/pymongo_base.py @@ -19,6 +19,7 @@ """ import pymongo +import ceilometer from ceilometer.openstack.common.gettextutils import _ from ceilometer.openstack.common import log from ceilometer.storage import base @@ -67,7 +68,7 @@ class Connection(base.Connection): """ if pagination: - raise NotImplementedError('Pagination not implemented') + raise ceilometer.NotImplementedError('Pagination not implemented') metaquery = metaquery or {} diff --git a/ceilometer/storage/sqlalchemy/utils.py b/ceilometer/storage/sqlalchemy/utils.py index c2f7954b2..ba198eafb 100644 --- a/ceilometer/storage/sqlalchemy/utils.py +++ b/ceilometer/storage/sqlalchemy/utils.py @@ -24,6 +24,7 @@ from sqlalchemy import not_ from sqlalchemy import or_ from sqlalchemy.orm import aliased +import ceilometer from ceilometer.storage.sqlalchemy import models @@ -79,8 +80,8 @@ class QueryTransformer(object): def _handle_metadata(self, op, field_name, value): if op == self.operators["in"]: - raise NotImplementedError('Metadata query with in ' - 'operator is not implemented') + raise ceilometer.NotImplementedError('Metadata query with in ' + 'operator is not implemented') field_name = field_name[len('resource_metadata.'):] meta_table = META_TYPE_MAP[type(value)] diff --git a/ceilometer/tests/base.py b/ceilometer/tests/base.py index a43d85669..b1b600148 100644 --- a/ceilometer/tests/base.py +++ b/ceilometer/tests/base.py @@ -27,7 +27,9 @@ from oslotest import base from oslotest import mockpatch import six from testtools import testcase +import webtest +import ceilometer from ceilometer import messaging @@ -95,11 +97,9 @@ def _skip_decorator(func): def skip_if_not_implemented(*args, **kwargs): try: return func(*args, **kwargs) - except AssertionError: - raise - except NotImplementedError as e: + except ceilometer.NotImplementedError as e: raise testcase.TestSkipped(six.text_type(e)) - except Exception as e: + except webtest.app.AppError as e: if 'not implemented' in six.text_type(e): raise testcase.TestSkipped(six.text_type(e)) raise diff --git a/ceilometer/tests/event/test_endpoint.py b/ceilometer/tests/event/test_endpoint.py index 3ffe07212..b872d5a2f 100644 --- a/ceilometer/tests/event/test_endpoint.py +++ b/ceilometer/tests/event/test_endpoint.py @@ -22,6 +22,7 @@ from oslo.config import fixture as fixture_config import oslo.messaging from stevedore import extension +import ceilometer from ceilometer.event import endpoint as event_endpoint from ceilometer.storage import models from ceilometer.tests import base as tests_base @@ -108,7 +109,8 @@ class TestEventEndpoint(tests_base.BaseTestCase): @mock.patch('ceilometer.event.endpoint.LOG') def test_event_not_implemented(self, log): - self.mock_dispatcher.record_events.side_effect = NotImplementedError + re = self.mock_dispatcher.record_events + re.side_effect = ceilometer.NotImplementedError message = {'event_type': "foo", 'message_id': "abc"} ret = self.endpoint.process_notification(message) log.warn.assert_called_once_with( diff --git a/ceilometer/tests/storage/test_storage_scenarios.py b/ceilometer/tests/storage/test_storage_scenarios.py index c8598c5a5..5318e9997 100644 --- a/ceilometer/tests/storage/test_storage_scenarios.py +++ b/ceilometer/tests/storage/test_storage_scenarios.py @@ -25,6 +25,7 @@ import operator import mock from oslo.utils import timeutils +import ceilometer from ceilometer.alarm.storage import models as alarm_models from ceilometer.publisher import utils from ceilometer import sample @@ -1536,7 +1537,7 @@ class StatisticsGroupByTest(DBTestBase, # error before list() is called. By using lambda, we can cover both # MongoDB and SQLAlchemy in a single test. self.assertRaises( - NotImplementedError, + ceilometer.NotImplementedError, lambda: list(self.conn.get_meter_statistics(f, groupby=['wtf'])) )