Tests verify that usage is as expected.

This commit is contained in:
Aurynn Shaw 2013-08-20 11:29:46 +12:00
parent edd184bef8
commit 85214fcbf4
4 changed files with 74 additions and 19 deletions

View File

@ -99,7 +99,6 @@ class Artifice(object):
password= config["openstack"]["password"], password= config["openstack"]["password"],
tenant_name= config["openstack"]["default_tenant"], tenant_name= config["openstack"]["default_tenant"],
auth_url= config["openstack"]["authentication_url"] auth_url= config["openstack"]["authentication_url"]
# auth_url="http://localhost:35357/v2.0"
) )
conn_string = 'postgresql://%(username)s:%(password)s@%(host)s:%(port)s/%(database)s' % { conn_string = 'postgresql://%(username)s:%(password)s@%(host)s:%(port)s/%(database)s' % {
"username": config["database"]["username"], "username": config["database"]["username"],
@ -373,16 +372,6 @@ class Usage(object):
vol.save() vol.save()
# self.db.begin()
# for
# for dc in self.contents.iterkeys():
# for section in self.contents[dc].iterkeys():
# for meter in self.contents[dc][section]:
# meter.save()
# self.conn.session.commit()
# raise NotImplementedError("Not implemented")
class Resource(object): class Resource(object):
def __init__(self, resource, conn): def __init__(self, resource, conn):
@ -564,6 +553,7 @@ class Gauge(Artifact):
""" """
Default billable number for this volume Default billable number for this volume
""" """
# print "Usage is %s" % self.usage
usage = sorted(self.usage, key=lambda x: x["timestamp"]) usage = sorted(self.usage, key=lambda x: x["timestamp"])
blocks = [] blocks = []
@ -573,11 +563,16 @@ class Gauge(Artifact):
last["timestamp"] = datetime.datetime.strptime(last["timestamp"], date_format) last["timestamp"] = datetime.datetime.strptime(last["timestamp"], date_format)
except ValueError: except ValueError:
last["timestamp"] = datetime.datetime.strptime(last["timestamp"], other_date_format) last["timestamp"] = datetime.datetime.strptime(last["timestamp"], other_date_format)
except TypeError:
pass
for val in usage[1:]: for val in usage[1:]:
try: try:
val["timestamp"] = datetime.datetime.strptime(val["timestamp"], date_format) val["timestamp"] = datetime.datetime.strptime(val["timestamp"], date_format)
except ValueError: except ValueError:
val["timestamp"] = datetime.datetime.strptime(val["timestamp"], other_date_format) val["timestamp"] = datetime.datetime.strptime(val["timestamp"], other_date_format)
except TypeError:
pass
if (val['timestamp'] - last["timestamp"]) > datetime.timedelta(hours=1): if (val['timestamp'] - last["timestamp"]) > datetime.timedelta(hours=1):
blocks.append(curr) blocks.append(curr)

View File

@ -28,6 +28,19 @@ class BaseModelConstruct(object):
def _fetch_meter_name(self, name): def _fetch_meter_name(self, name):
return name return name
def usage(self):
dct = {}
for meter in self.relevant_meters:
meter = self._fetch_meter_name(meter)
try:
vol = self._raw.meter(meter, self.start, self.end).volume()
dct[meter] = vol
except AttributeError:
# This is OK. We're not worried about non-existent meters,
# I think. For now, anyway.
pass
return dct
def save(self): def save(self):
for meter in self.relevant_meters: for meter in self.relevant_meters:
meter = self._fetch_meter_name(meter) meter = self._fetch_meter_name(meter)
@ -78,6 +91,10 @@ class VM(BaseModelConstruct):
"""floating IPs; this is a metered value""" """floating IPs; this is a metered value"""
return 0 return 0
@property
def name(self):
return self._raw["metadata"]["display_name"]
class Object(BaseModelConstruct): class Object(BaseModelConstruct):

View File

@ -15,7 +15,7 @@ class TestInstancing(unittest.TestCase):
pass pass
@mock.patch("artifice.models.Session") @mock.patch("artifice.models.Session")
@mock.patch("keystoneclient.v2_0.client.Client") @mock.patch("artifice.interface.keystone")
@mock.patch("sqlalchemy.create_engine") @mock.patch("sqlalchemy.create_engine")
def test_instance_artifice(self, sqlmock, keystone, session): def test_instance_artifice(self, sqlmock, keystone, session):
@ -26,19 +26,24 @@ class TestInstancing(unittest.TestCase):
config = { config = {
"main": {}, "main": {},
"database": { "database": {
"username": "foo", "username": "aurynn",
"password": "bar", "password": "aurynn",
"host": "1234", "host": "localhost",
"port": "1234", "port": "5433",
"database": "artifice" "database": "artifice"
}, },
"openstack": { "openstack": {
"username": "foo", "username": "foo",
"password": "bar", "password": "bar",
"default_tenant":"asdf", "default_tenant":"asdf",
"authentication_url": "foo" "authentication_url": "http://foo"
}, },
"invoice": {} "ceilometer": {
"host": 'http://whee'
},
"invoices": {
"plugin": "json"
}
} }
a = Artifice(config) a = Artifice(config)

View File

@ -323,7 +323,45 @@ class TestInterface(unittest.TestCase):
# Now examine the database # Now examine the database
def test_correct_usage_values(self): def test_correct_usage_values(self):
pass """Usage data matches expected results:
tests that we get the usage data we expect from the processing
system as developed.
"""
self.test_get_usage()
usage = self.usage
for vm in usage.vms:
volume = vm.usage()
# print "vm is %s" % vm
# print vm.size
# print "Volume is: %s" % volume
# VM here is a resource object, not an underlying meter object.
id_ = vm["project_id"]
for rvm in self.resources:
if not rvm["project_id"] == id_:
continue
for meter in rvm["links"]:
if not meter["rel"] in volume:
continue
data = mappings[ meter["href"] ]
vol = volume[ meter["rel"] ]
type_ = data[0]["counter_type"]
if type_ == "cumulative":
v = interface.Cumulative(rvm, data, self.start, self.end)
elif type_ == "gauge":
v = interface.Gauge(rvm, data, self.start, self.end)
elif type_ == "delta":
v = interface.Delta(rvm, data, self.start, self.end)
# Same type of data
self.assertEqual( v.__class__, vol.__class__ )
# Why are these different?
self.assertEqual( v.volume(), vol.volume() )
def test_use_a_bunch_of_data(self): def test_use_a_bunch_of_data(self):
pass pass