diff --git a/artifice/interface.py b/artifice/interface.py index 0340d2a..9b67a18 100644 --- a/artifice/interface.py +++ b/artifice/interface.py @@ -99,7 +99,6 @@ class Artifice(object): password= config["openstack"]["password"], tenant_name= config["openstack"]["default_tenant"], 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' % { "username": config["database"]["username"], @@ -373,16 +372,6 @@ class Usage(object): 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): def __init__(self, resource, conn): @@ -564,6 +553,7 @@ class Gauge(Artifact): """ Default billable number for this volume """ + # print "Usage is %s" % self.usage usage = sorted(self.usage, key=lambda x: x["timestamp"]) blocks = [] @@ -573,11 +563,16 @@ class Gauge(Artifact): last["timestamp"] = datetime.datetime.strptime(last["timestamp"], date_format) except ValueError: last["timestamp"] = datetime.datetime.strptime(last["timestamp"], other_date_format) + except TypeError: + pass + for val in usage[1:]: try: val["timestamp"] = datetime.datetime.strptime(val["timestamp"], date_format) except ValueError: val["timestamp"] = datetime.datetime.strptime(val["timestamp"], other_date_format) + except TypeError: + pass if (val['timestamp'] - last["timestamp"]) > datetime.timedelta(hours=1): blocks.append(curr) diff --git a/artifice/models/resources.py b/artifice/models/resources.py index 4db6e0e..f29158a 100644 --- a/artifice/models/resources.py +++ b/artifice/models/resources.py @@ -28,6 +28,19 @@ class BaseModelConstruct(object): def _fetch_meter_name(self, 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): for meter in self.relevant_meters: meter = self._fetch_meter_name(meter) @@ -78,6 +91,10 @@ class VM(BaseModelConstruct): """floating IPs; this is a metered value""" return 0 + @property + def name(self): + return self._raw["metadata"]["display_name"] + class Object(BaseModelConstruct): diff --git a/tests/test_instancing_objects.py b/tests/test_instancing_objects.py index 85b550e..263e692 100644 --- a/tests/test_instancing_objects.py +++ b/tests/test_instancing_objects.py @@ -15,7 +15,7 @@ class TestInstancing(unittest.TestCase): pass @mock.patch("artifice.models.Session") - @mock.patch("keystoneclient.v2_0.client.Client") + @mock.patch("artifice.interface.keystone") @mock.patch("sqlalchemy.create_engine") def test_instance_artifice(self, sqlmock, keystone, session): @@ -26,19 +26,24 @@ class TestInstancing(unittest.TestCase): config = { "main": {}, "database": { - "username": "foo", - "password": "bar", - "host": "1234", - "port": "1234", + "username": "aurynn", + "password": "aurynn", + "host": "localhost", + "port": "5433", "database": "artifice" }, "openstack": { "username": "foo", "password": "bar", "default_tenant":"asdf", - "authentication_url": "foo" + "authentication_url": "http://foo" }, - "invoice": {} + "ceilometer": { + "host": 'http://whee' + }, + "invoices": { + "plugin": "json" + } } a = Artifice(config) diff --git a/tests/test_interface.py b/tests/test_interface.py index 7147efc..10165eb 100644 --- a/tests/test_interface.py +++ b/tests/test_interface.py @@ -323,7 +323,45 @@ class TestInterface(unittest.TestCase): # Now examine the database 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): pass