Change the column counter_volume to Float

counter_volume was previously an Integer (32 bits value in SQL
implementations as MySQL or PostgreSQL) and limited in values from
-2147483648 to 2147483647, very small for things like disk I/O bytes,
network I/O bytes, image size, object size, volume size, …
Furthermore one might want to store some real numbers (ℝ) (temperatures,
power comsumption, …)

Change-Id: Ifdb8e8e84e8e01df267d71bc72cdc3f56bb2f695
Fixes: bug #1158276
This commit is contained in:
François Charlier 2013-03-21 16:21:11 +01:00
parent 86ebece007
commit d09b7b7226
6 changed files with 126 additions and 2 deletions

View File

@ -0,0 +1,32 @@
# -*- encoding: utf-8 -*-
#
# Copyright © 2013 eNovance SAS <licensing@enovance.com>
# Author: François Charlier <francois.charlier@enovance.com>
#
# 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 sqlalchemy import *
meta = MetaData()
def upgrade(migrate_engine):
meta.bind = migrate_engine
meter = Table('meter', meta, autoload=True)
meter.c.counter_volume.alter(type=Float(53))
def downgrade(migrate_engine):
meta.bind = migrate_engine
meter = Table('meter', meta, autoload=True)
meter.c.counter_volume.alter(type=Integer)

View File

@ -22,7 +22,8 @@ import json
import urlparse
from oslo.config import cfg
from sqlalchemy import Column, Integer, String, Table, ForeignKey, DateTime
from sqlalchemy import Column, Integer, String, Table, ForeignKey, DateTime, \
Float
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship
from sqlalchemy.types import TypeDecorator, VARCHAR
@ -108,7 +109,7 @@ class Meter(Base):
resource_metadata = Column(JSONEncodedDict)
counter_type = Column(String(255))
counter_unit = Column(String(255))
counter_volume = Column(Integer)
counter_volume = Column(Float(53))
timestamp = Column(DateTime, default=timeutils.utcnow)
message_signature = Column(String)
message_id = Column(String)

View File

@ -878,3 +878,82 @@ class StatisticsTest(DBTestBase):
assert results['max'] == 7
assert results['sum'] == 18
assert results['avg'] == 6
class CounterDataTypeTest(DBTestBase):
def prepare_data(self):
c = counter.Counter(
'dummyBigCounter',
counter.TYPE_CUMULATIVE,
unit='',
volume=3372036854775807,
user_id='user-id',
project_id='project-id',
resource_id='resource-id',
timestamp=datetime.datetime(2012, 7, 2, 10, 40),
resource_metadata={}
)
msg = meter.meter_message_from_counter(
c,
cfg.CONF.metering_secret,
'test-1',
)
self.conn.record_metering_data(msg)
c = counter.Counter(
'dummySmallCounter',
counter.TYPE_CUMULATIVE,
unit='',
volume=-3372036854775807,
user_id='user-id',
project_id='project-id',
resource_id='resource-id',
timestamp=datetime.datetime(2012, 7, 2, 10, 40),
resource_metadata={}
)
msg = meter.meter_message_from_counter(
c,
cfg.CONF.metering_secret,
'test-1',
)
self.conn.record_metering_data(msg)
c = counter.Counter(
'floatCounter',
counter.TYPE_CUMULATIVE,
unit='',
volume=1938495037.53697,
user_id='user-id',
project_id='project-id',
resource_id='resource-id',
timestamp=datetime.datetime(2012, 7, 2, 10, 40),
resource_metadata={}
)
msg = meter.meter_message_from_counter(
c,
cfg.CONF.metering_secret,
'test-1',
)
self.conn.record_metering_data(msg)
def test_storage_can_handle_large_values(self):
f = storage.EventFilter(
meter='dummyBigCounter',
)
results = list(self.conn.get_samples(f))
self.assertEqual(results[0]['counter_volume'], 3372036854775807)
f = storage.EventFilter(
meter='dummySmallCounter',
)
results = list(self.conn.get_samples(f))
self.assertEqual(results[0]['counter_volume'], -3372036854775807)
def test_storage_can_handle_float_values(self):
f = storage.EventFilter(
meter='floatCounter',
)
results = list(self.conn.get_samples(f))
self.assertEqual(results[0]['counter_volume'], 1938495037.53697)

View File

@ -177,6 +177,10 @@ class StatisticsTest(base.StatisticsTest, HBaseEngineTestBase):
pass
class CounterDataTypeTest(base.CounterDataTypeTest, HBaseEngineTestBase):
pass
###############
# This is a very crude version of "in-memory HBase", which implements just
# enough functionality of HappyBase API to support testing of our driver.

View File

@ -226,3 +226,7 @@ class CompatibilityTest(MongoDBEngineTestBase):
def test_counter_unit(self):
meters = list(self.conn.get_meters())
self.assertEqual(len(meters), 1)
class CounterDataTypeTest(base.CounterDataTypeTest, MongoDBEngineTestBase):
pass

View File

@ -135,6 +135,10 @@ class StatisticsTest(base.StatisticsTest, SQLAlchemyEngineTestBase):
pass
class CounterDataTypeTest(base.CounterDataTypeTest, SQLAlchemyEngineTestBase):
pass
def test_model_table_args():
cfg.CONF.database_connection = 'mysql://localhost'
assert table_args()