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 <julien@danjou.info>
This commit is contained in:
Julien Danjou 2013-04-04 13:52:22 +02:00
parent 011392c02a
commit 93fa81e116
11 changed files with 23 additions and 223 deletions

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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<values.length; i++ ) {
if ( values[i].min < res.min )
res.min = values[i].min;
if ( values[i].max > 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.

View File

@ -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'),

View File

@ -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(),

View File

@ -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):

View File

@ -51,11 +51,6 @@ class RawEventTest(base.RawEventTest, HBaseEngineTestBase):
pass
class TestGetEventInterval(base.TestGetEventInterval,
HBaseEngineTestBase):
pass
class StatisticsTest(base.StatisticsTest, HBaseEngineTestBase):
pass

View File

@ -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):

View File

@ -53,11 +53,6 @@ class RawEventTest(base.RawEventTest, SQLAlchemyEngineTestBase):
pass
class TestGetEventInterval(base.TestGetEventInterval,
SQLAlchemyEngineTestBase):
pass
class StatisticsTest(base.StatisticsTest, SQLAlchemyEngineTestBase):
pass