From 93fa81e116ecc745e4820abd1f7b38d2d5270d33 Mon Sep 17 00:00:00 2001 From: Julien Danjou Date: Thu, 4 Apr 2013 13:52:22 +0200 Subject: [PATCH] storage: get rid of get_event_interval This is part of blueprint remove-obsolete-storage-driver-methods Change-Id: I8ee25af4cf7e3db2605e3d9586e28327f1ba321e Signed-off-by: Julien Danjou --- ceilometer/api/v1/blueprint.py | 3 +- ceilometer/storage/base.py | 8 -- ceilometer/storage/impl_hbase.py | 26 ------ ceilometer/storage/impl_log.py | 5 -- ceilometer/storage/impl_mongodb.py | 39 -------- ceilometer/storage/impl_sqlalchemy.py | 13 --- tests/api/v1/compute_duration_by_resource.py | 40 +++++---- tests/storage/base.py | 95 -------------------- tests/storage/test_impl_hbase.py | 5 -- tests/storage/test_impl_mongodb.py | 7 -- tests/storage/test_impl_sqlalchemy.py | 5 -- 11 files changed, 23 insertions(+), 223 deletions(-) diff --git a/ceilometer/api/v1/blueprint.py b/ceilometer/api/v1/blueprint.py index 2b837fc49..a75058d70 100644 --- a/ceilometer/api/v1/blueprint.py +++ b/ceilometer/api/v1/blueprint.py @@ -559,7 +559,8 @@ def compute_duration_by_resource(resource, meter): start=q_ts['query_start'], end=q_ts['query_end'], ) - min_ts, max_ts = flask.request.storage_conn.get_event_interval(f) + stats = flask.request.storage_conn.get_meter_statistics(f) + min_ts, max_ts = stats.duration_start, stats.duration_end # "Clamp" the timestamps we return to the original time # range, excluding the offset. diff --git a/ceilometer/storage/base.py b/ceilometer/storage/base.py index 0ac22a007..45dc6aa5f 100644 --- a/ceilometer/storage/base.py +++ b/ceilometer/storage/base.py @@ -130,14 +130,6 @@ class Connection(object): """Return an iterable of model.Sample instances """ - @abc.abstractmethod - def get_event_interval(self, event_filter): - """Return the min and max timestamps from samples, - using the event_filter to limit the samples seen. - - ( datetime.datetime(), datetime.datetime() ) - """ - @abc.abstractmethod def get_meter_statistics(self, event_filter, period=None): """Return an iterable of model.Statistics instances diff --git a/ceilometer/storage/impl_hbase.py b/ceilometer/storage/impl_hbase.py index 6e07bcd71..1aad05a17 100644 --- a/ceilometer/storage/impl_hbase.py +++ b/ceilometer/storage/impl_hbase.py @@ -494,32 +494,6 @@ class Connection(base.Connection): self._update_meter_stats(results[-1], meter) return results - def get_event_interval(self, event_filter): - """Return the min and max timestamps from samples, - using the event_filter to limit the samples seen. - - ( datetime.datetime(), datetime.datetime() ) - """ - q, start, stop = make_query_from_filter(event_filter) - LOG.debug("q: %s" % q) - gen = self.meter.scan(filter=q, row_start=start, row_stop=stop) - a_min = None - a_max = None - for ignored, meter in gen: - timestamp = timeutils.parse_strtime(meter['f:timestamp']) - if a_min is None: - a_min = timestamp - else: - if timestamp < a_min: - a_min = timestamp - if a_max is None: - a_max = timestamp - else: - if timestamp > a_max: - a_max = timestamp - - return a_min, a_max - ############### # This is a very crude version of "in-memory HBase", which implements just diff --git a/ceilometer/storage/impl_log.py b/ceilometer/storage/impl_log.py index b46a3df96..4636d6dbe 100644 --- a/ceilometer/storage/impl_log.py +++ b/ceilometer/storage/impl_log.py @@ -124,11 +124,6 @@ class Connection(base.Connection): """ return [] - def get_event_interval(self, event_filter): - """Return the min and max timestamp for samples - matching the event_filter. - """ - def get_meter_statistics(self, event_filter, period=None): """Return a dictionary containing meter statistics. described by the query parameters. diff --git a/ceilometer/storage/impl_mongodb.py b/ceilometer/storage/impl_mongodb.py index 2cce3467b..0ba5e1139 100644 --- a/ceilometer/storage/impl_mongodb.py +++ b/ceilometer/storage/impl_mongodb.py @@ -133,28 +133,6 @@ class Connection(base.Connection): _mim_instance = None - # MAP_TIMESTAMP and REDUCE_MIN_MAX are based on the recipe - # http://cookbook.mongodb.org/patterns/finding_max_and_min_values_for_a_key - MAP_TIMESTAMP = bson.code.Code(""" - function () { - emit('timestamp', { min : this.timestamp, - max : this.timestamp } ) - } - """) - - REDUCE_MIN_MAX = bson.code.Code(""" - function (key, values) { - var res = values[0]; - for ( var i=1; i res.max ) - res.max = values[i].max; - } - return res; - } - """) - MAP_STATS = bson.code.Code(""" function () { emit('statistics', { min : this.counter_volume, @@ -528,23 +506,6 @@ class Connection(base.Connection): a_max.valueOf() // 1000) return (a_min, a_max) - def get_event_interval(self, event_filter): - """Return the min and max timestamps from samples, - using the event_filter to limit the samples seen. - - ( datetime.datetime(), datetime.datetime() ) - """ - q = make_query_from_filter(event_filter) - results = self.db.meter.map_reduce(self.MAP_TIMESTAMP, - self.REDUCE_MIN_MAX, - {'inline': 1}, - query=q, - ) - if results['results']: - answer = results['results'][0]['value'] - return self._fix_interval_min_max(answer['min'], answer['max']) - return (None, None) - def require_map_reduce(conn): """Raises SkipTest if the connection is using mim. diff --git a/ceilometer/storage/impl_sqlalchemy.py b/ceilometer/storage/impl_sqlalchemy.py index 2ec1dbe52..75e5c1ef4 100644 --- a/ceilometer/storage/impl_sqlalchemy.py +++ b/ceilometer/storage/impl_sqlalchemy.py @@ -344,19 +344,6 @@ class Connection(base.Connection): mainq = mainq.join(Meter).group_by(Resource.id) return mainq.filter(Meter.id.in_(subq)) - def get_event_interval(self, event_filter): - """Return the min and max timestamps from samples, - using the event_filter to limit the samples seen. - - ( datetime.datetime(), datetime.datetime() ) - """ - query = self.session.query(func.min(Meter.timestamp), - func.max(Meter.timestamp)) - query = make_query_from_filter(query, event_filter) - results = query.all() - a_min, a_max = results[0] - return (a_min, a_max) - def _make_stats_query(self, event_filter): query = self.session.query( func.min(Meter.timestamp).label('tsmin'), diff --git a/tests/api/v1/compute_duration_by_resource.py b/tests/api/v1/compute_duration_by_resource.py index 3dd1826c3..99a360adf 100644 --- a/tests/api/v1/compute_duration_by_resource.py +++ b/tests/api/v1/compute_duration_by_resource.py @@ -22,7 +22,7 @@ import datetime import logging from ceilometer.openstack.common import timeutils - +from ceilometer.storage import models from ceilometer.tests import api as tests_api LOG = logging.getLogger(__name__) @@ -49,12 +49,18 @@ class TestComputeDurationByResource(tests_api.TestBase): self.late1 = datetime.datetime(2012, 8, 29, 9, 0) self.late2 = datetime.datetime(2012, 8, 29, 19, 0) - def _set_interval(self, start, end): - def get_interval(event_filter): - assert event_filter.start - assert event_filter.end - return (start, end) - self.stubs.Set(self.conn, 'get_event_interval', get_interval) + def _set_stats(self, start, end): + def get_meter_statistics(event_filter): + return models.Statistics( + min=0, max=0, avg=0, sum=0, count=0, + period=None, + period_start=None, + period_end=None, + duration=end - start, + duration_start=start, + duration_end=end) + self.stubs.Set(self.conn, 'get_meter_statistics', + get_meter_statistics) def _invoke_api(self): return self.get( @@ -65,7 +71,7 @@ class TestComputeDurationByResource(tests_api.TestBase): ) def test_before_range(self): - self._set_interval(self.early1, self.early2) + self._set_stats(self.early1, self.early2) data = self._invoke_api() assert data['start_timestamp'] is None assert data['end_timestamp'] is None @@ -76,44 +82,42 @@ class TestComputeDurationByResource(tests_api.TestBase): assert actual == expected def test_overlap_range_start(self): - self._set_interval(self.early1, self.middle1) + self._set_stats(self.early1, self.middle1) data = self._invoke_api() self._assert_times_match(data['start_timestamp'], self.start) self._assert_times_match(data['end_timestamp'], self.middle1) self.assertEqual(data['duration'], 8 * 60 * 60) def test_within_range(self): - self._set_interval(self.middle1, self.middle2) + self._set_stats(self.middle1, self.middle2) data = self._invoke_api() self._assert_times_match(data['start_timestamp'], self.middle1) self._assert_times_match(data['end_timestamp'], self.middle2) self.assertEqual(data['duration'], 10 * 60 * 60) def test_within_range_zero_duration(self): - self._set_interval(self.middle1, self.middle1) + self._set_stats(self.middle1, self.middle1) data = self._invoke_api() self._assert_times_match(data['start_timestamp'], self.middle1) self._assert_times_match(data['end_timestamp'], self.middle1) assert data['duration'] == 0 def test_overlap_range_end(self): - self._set_interval(self.middle2, self.late1) + self._set_stats(self.middle2, self.late1) data = self._invoke_api() self._assert_times_match(data['start_timestamp'], self.middle2) self._assert_times_match(data['end_timestamp'], self.end) self.assertEqual(data['duration'], ((6 * 60) - 1) * 60) def test_after_range(self): - self._set_interval(self.late1, self.late2) + self._set_stats(self.late1, self.late2) data = self._invoke_api() assert data['start_timestamp'] is None assert data['end_timestamp'] is None assert data['duration'] is None def test_without_end_timestamp(self): - def get_interval(event_filter): - return (self.late1, self.late2) - self.stubs.Set(self.conn, 'get_event_interval', get_interval) + self._set_stats(self.late1, self.late2) data = self.get( '/resources/resource-id/meters/instance:m1.tiny/duration', start_timestamp=self.late1.isoformat(), @@ -123,9 +127,7 @@ class TestComputeDurationByResource(tests_api.TestBase): self._assert_times_match(data['end_timestamp'], self.late2) def test_without_start_timestamp(self): - def get_interval(event_filter): - return (self.early1, self.early2) - self.stubs.Set(self.conn, 'get_event_interval', get_interval) + self._set_stats(self.early1, self.early2) data = self.get( '/resources/resource-id/meters/instance:m1.tiny/duration', end_timestamp=self.early2.isoformat(), diff --git a/tests/storage/base.py b/tests/storage/base.py index 33673023d..f2d371fa9 100644 --- a/tests/storage/base.py +++ b/tests/storage/base.py @@ -340,101 +340,6 @@ class RawEventTest(DBTestBase): assert len(results) == 1 -class TestGetEventInterval(DBTestBase): - - def setUp(self): - super(TestGetEventInterval, self).setUp() - - # Create events relative to the range and pretend - # that the intervening events exist. - - self.start = datetime.datetime(2012, 8, 28, 0, 0) - self.end = datetime.datetime(2012, 8, 29, 0, 0) - - self.early1 = self.start - datetime.timedelta(minutes=20) - self.early2 = self.start - datetime.timedelta(minutes=10) - - self.middle1 = self.start + datetime.timedelta(minutes=10) - self.middle2 = self.end - datetime.timedelta(minutes=10) - - self.late1 = self.end + datetime.timedelta(minutes=10) - self.late2 = self.end + datetime.timedelta(minutes=20) - - self._filter = storage.EventFilter( - resource='111', - meter='instance', - start=self.start, - end=self.end, - ) - - def _make_events(self, *timestamps): - for t in timestamps: - c = counter.Counter( - 'instance', - counter.TYPE_CUMULATIVE, - '', - 1, - '11', - '1', - '111', - timestamp=t, - resource_metadata={'display_name': 'test-server', - } - ) - msg = meter.meter_message_from_counter(c, cfg.CONF.metering_secret, - 'test') - self.conn.record_metering_data(msg) - - def test_before_range(self): - self._make_events(self.early1, self.early2) - s, e = self.conn.get_event_interval(self._filter) - assert s is None - assert e is None - - def test_overlap_range_start(self): - self._make_events(self.early1, self.start, self.middle1) - s, e = self.conn.get_event_interval(self._filter) - assert s == self.start - assert e == self.middle1 - - def test_within_range(self): - self._make_events(self.middle1, self.middle2) - s, e = self.conn.get_event_interval(self._filter) - assert s == self.middle1 - assert e == self.middle2 - - def test_within_range_zero_duration(self): - self._make_events(self.middle1) - s, e = self.conn.get_event_interval(self._filter) - assert s == self.middle1 - assert e == self.middle1 - - def test_within_range_zero_duration_two_events(self): - self._make_events(self.middle1, self.middle1) - s, e = self.conn.get_event_interval(self._filter) - assert s == self.middle1 - assert e == self.middle1 - - def test_overlap_range_end(self): - self._make_events(self.middle2, self.end, self.late1) - s, e = self.conn.get_event_interval(self._filter) - assert s == self.middle2 - assert e == self.middle2 - - def test_overlap_range_end_with_offset(self): - self._make_events(self.middle2, self.end, self.late1) - self._filter.end = self.late1 - s, e = self.conn.get_event_interval(self._filter) - assert s == self.middle2 - assert e == self.end - - def test_after_range(self): - self._make_events(self.late1, self.late2) - s, e = self.conn.get_event_interval(self._filter) - assert s is None - assert e is None - - class StatisticsTest(DBTestBase): def prepare_data(self): diff --git a/tests/storage/test_impl_hbase.py b/tests/storage/test_impl_hbase.py index db3b58855..20efa51c4 100644 --- a/tests/storage/test_impl_hbase.py +++ b/tests/storage/test_impl_hbase.py @@ -51,11 +51,6 @@ class RawEventTest(base.RawEventTest, HBaseEngineTestBase): pass -class TestGetEventInterval(base.TestGetEventInterval, - HBaseEngineTestBase): - pass - - class StatisticsTest(base.StatisticsTest, HBaseEngineTestBase): pass diff --git a/tests/storage/test_impl_mongodb.py b/tests/storage/test_impl_mongodb.py index 3d163a68e..cc73f2aa6 100644 --- a/tests/storage/test_impl_mongodb.py +++ b/tests/storage/test_impl_mongodb.py @@ -90,13 +90,6 @@ class RawEventTest(base.RawEventTest, MongoDBEngineTestBase): pass -class TestGetEventInterval(base.TestGetEventInterval, MongoDBEngineTestBase): - - def setUp(self): - super(TestGetEventInterval, self).setUp() - require_map_reduce(self.conn) - - class StatisticsTest(base.StatisticsTest, MongoDBEngineTestBase): def setUp(self): diff --git a/tests/storage/test_impl_sqlalchemy.py b/tests/storage/test_impl_sqlalchemy.py index 59476a960..44273f796 100644 --- a/tests/storage/test_impl_sqlalchemy.py +++ b/tests/storage/test_impl_sqlalchemy.py @@ -53,11 +53,6 @@ class RawEventTest(base.RawEventTest, SQLAlchemyEngineTestBase): pass -class TestGetEventInterval(base.TestGetEventInterval, - SQLAlchemyEngineTestBase): - pass - - class StatisticsTest(base.StatisticsTest, SQLAlchemyEngineTestBase): pass