Merge "Add bandwidth usage object"
This commit is contained in:
commit
deacd9d1cc
@ -26,6 +26,7 @@ def register_all():
|
||||
# need to receive it via RPC.
|
||||
__import__('nova.objects.agent')
|
||||
__import__('nova.objects.aggregate')
|
||||
__import__('nova.objects.bandwidth_usage')
|
||||
__import__('nova.objects.block_device')
|
||||
__import__('nova.objects.compute_node')
|
||||
__import__('nova.objects.dns_domain')
|
||||
|
76
nova/objects/bandwidth_usage.py
Normal file
76
nova/objects/bandwidth_usage.py
Normal file
@ -0,0 +1,76 @@
|
||||
# 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 nova import db
|
||||
from nova.objects import base
|
||||
from nova.objects import fields
|
||||
|
||||
|
||||
class BandwidthUsage(base.NovaPersistentObject, base.NovaObject):
|
||||
# Version 1.0: Initial version
|
||||
VERSION = '1.0'
|
||||
|
||||
fields = {
|
||||
'instance_uuid': fields.UUIDField(),
|
||||
'mac': fields.StringField(),
|
||||
'start_period': fields.DateTimeField(),
|
||||
'last_refreshed': fields.DateTimeField(),
|
||||
'bw_in': fields.IntegerField(),
|
||||
'bw_out': fields.IntegerField(),
|
||||
'last_ctr_in': fields.IntegerField(),
|
||||
'last_ctr_out': fields.IntegerField()
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def _from_db_object(context, bw_usage, db_bw_usage):
|
||||
for field in bw_usage.fields:
|
||||
bw_usage[field] = db_bw_usage[field]
|
||||
bw_usage._context = context
|
||||
bw_usage.obj_reset_changes()
|
||||
return bw_usage
|
||||
|
||||
@base.serialize_args
|
||||
@base.remotable_classmethod
|
||||
def get_by_instance_uuid_and_mac(cls, context, instance_uuid, mac,
|
||||
start_period=None):
|
||||
db_bw_usage = db.bw_usage_get(context, uuid=instance_uuid,
|
||||
start_period=start_period, mac=mac)
|
||||
if db_bw_usage:
|
||||
return cls._from_db_object(context, cls(), db_bw_usage)
|
||||
|
||||
@base.serialize_args
|
||||
@base.remotable
|
||||
def create(self, context, uuid, mac, bw_in, bw_out, last_ctr_in,
|
||||
last_ctr_out, start_period=None, last_refreshed=None):
|
||||
db_bw_usage = db.bw_usage_update(
|
||||
context, uuid, mac, start_period, bw_in, bw_out,
|
||||
last_ctr_in, last_ctr_out, last_refreshed=last_refreshed)
|
||||
|
||||
self._from_db_object(context, self, db_bw_usage)
|
||||
|
||||
|
||||
class BandwidthUsageList(base.ObjectListBase, base.NovaObject):
|
||||
# Version 1.0: Initial version
|
||||
VERSION = '1.0'
|
||||
fields = {
|
||||
'objects': fields.ListOfObjectsField('BandwidthUsage'),
|
||||
}
|
||||
child_versions = {
|
||||
'1.0': '1.0',
|
||||
}
|
||||
|
||||
@base.serialize_args
|
||||
@base.remotable_classmethod
|
||||
def get_by_uuids(cls, context, uuids, start_period=None):
|
||||
db_bw_usages = db.bw_usage_get_by_uuids(context, uuids=uuids,
|
||||
start_period=start_period)
|
||||
return base.obj_make_list(context, cls(), BandwidthUsage, db_bw_usages)
|
@ -16,6 +16,7 @@
|
||||
|
||||
import collections
|
||||
import copy
|
||||
import datetime
|
||||
import functools
|
||||
import traceback
|
||||
|
||||
@ -29,6 +30,7 @@ from nova.i18n import _, _LE
|
||||
from nova import objects
|
||||
from nova.objects import fields
|
||||
from nova.openstack.common import log as logging
|
||||
from nova.openstack.common import timeutils
|
||||
from nova.openstack.common import versionutils
|
||||
|
||||
|
||||
@ -709,18 +711,23 @@ def obj_make_list(context, list_obj, item_cls, db_list, **extra_args):
|
||||
|
||||
def serialize_args(fn):
|
||||
"""Decorator that will do the arguments serialization before remoting."""
|
||||
def wrapper(cls, *args, **kwargs):
|
||||
def wrapper(obj, *args, **kwargs):
|
||||
for kw in kwargs:
|
||||
value_arg = kwargs.get(kw)
|
||||
if kw == 'exc_val' and value_arg:
|
||||
kwargs[kw] = str(value_arg)
|
||||
if kw == 'exc_tb' and (
|
||||
elif kw == 'exc_tb' and (
|
||||
not isinstance(value_arg, six.string_types) and value_arg):
|
||||
kwargs[kw] = ''.join(traceback.format_tb(value_arg))
|
||||
elif isinstance(value_arg, datetime.datetime):
|
||||
kwargs[kw] = timeutils.isotime(value_arg)
|
||||
if hasattr(fn, '__call__'):
|
||||
return fn(obj, *args, **kwargs)
|
||||
# NOTE(danms): We wrap a descriptor, so use that protocol
|
||||
return fn.__get__(None, cls)(*args, **kwargs)
|
||||
return fn.__get__(None, obj)(*args, **kwargs)
|
||||
|
||||
# NOTE(danms): Make this discoverable
|
||||
wrapper.remotable = getattr(fn, 'remotable', False)
|
||||
wrapper.original_fn = fn
|
||||
return classmethod(wrapper)
|
||||
return (functools.wraps(fn)(wrapper) if hasattr(fn, '__call__')
|
||||
else classmethod(wrapper))
|
||||
|
124
nova/tests/objects/test_bandwidth_usage.py
Normal file
124
nova/tests/objects/test_bandwidth_usage.py
Normal file
@ -0,0 +1,124 @@
|
||||
# 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.
|
||||
|
||||
import datetime
|
||||
|
||||
import iso8601
|
||||
import mock
|
||||
|
||||
from nova import context
|
||||
from nova import db
|
||||
from nova.objects import bandwidth_usage
|
||||
from nova.openstack.common import timeutils
|
||||
from nova import test
|
||||
from nova.tests.objects import test_objects
|
||||
|
||||
|
||||
class _TestBandwidthUsage(test.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(_TestBandwidthUsage, self).setUp()
|
||||
self.user_id = 'fake_user'
|
||||
self.project_id = 'fake_project'
|
||||
self.context = context.RequestContext(self.user_id, self.project_id)
|
||||
now, start_period = self._time_now_and_start_period()
|
||||
self.expected_bw_usage = self._fake_bw_usage(
|
||||
time=now, start_period=start_period)
|
||||
|
||||
@staticmethod
|
||||
def _compare(test, db, obj):
|
||||
for field, value in db.items():
|
||||
test.assertEqual(db[field], obj[field])
|
||||
|
||||
@staticmethod
|
||||
def _fake_bw_usage(time=None, start_period=None, bw_in=100,
|
||||
bw_out=200, last_ctr_in=12345, last_ctr_out=67890):
|
||||
fake_bw_usage = {
|
||||
'created_at': None,
|
||||
'updated_at': None,
|
||||
'deleted_at': None,
|
||||
'deleted': 0,
|
||||
'instance_uuid': 'fake_uuid1',
|
||||
'mac': 'fake_mac1',
|
||||
'start_period': start_period,
|
||||
'bw_in': bw_in,
|
||||
'bw_out': bw_out,
|
||||
'last_ctr_in': last_ctr_in,
|
||||
'last_ctr_out': last_ctr_out,
|
||||
'last_refreshed': time
|
||||
}
|
||||
return fake_bw_usage
|
||||
|
||||
@staticmethod
|
||||
def _time_now_and_start_period():
|
||||
now = timeutils.utcnow().replace(tzinfo=iso8601.iso8601.Utc(),
|
||||
microsecond=0)
|
||||
start_period = now - datetime.timedelta(seconds=10)
|
||||
return now, start_period
|
||||
|
||||
@mock.patch.object(db, 'bw_usage_get')
|
||||
def test_get_by_instance_uuid_and_mac(self, mock_get):
|
||||
mock_get.return_value = self.expected_bw_usage
|
||||
bw_usage = bandwidth_usage.BandwidthUsage.get_by_instance_uuid_and_mac(
|
||||
self.context, 'fake_uuid', 'fake_mac',
|
||||
start_period=self.expected_bw_usage['start_period'])
|
||||
self._compare(self, self.expected_bw_usage, bw_usage)
|
||||
|
||||
@mock.patch.object(db, 'bw_usage_get_by_uuids')
|
||||
def test_get_by_uuids(self, mock_get_by_uuids):
|
||||
mock_get_by_uuids.return_value = [self.expected_bw_usage]
|
||||
|
||||
bw_usages = bandwidth_usage.BandwidthUsageList.get_by_uuids(
|
||||
self.context, ['fake_uuid'],
|
||||
start_period=self.expected_bw_usage['start_period'])
|
||||
self.assertEqual(len(bw_usages), 1)
|
||||
self._compare(self, self.expected_bw_usage, bw_usages[0])
|
||||
|
||||
@mock.patch.object(db, 'bw_usage_update')
|
||||
def test_create(self, mock_create):
|
||||
mock_create.return_value = self.expected_bw_usage
|
||||
|
||||
bw_usage = bandwidth_usage.BandwidthUsage()
|
||||
bw_usage.create(self.context, 'fake_uuid', 'fake_mac',
|
||||
100, 200, 12345, 67890,
|
||||
start_period=self.expected_bw_usage['start_period'])
|
||||
|
||||
self._compare(self, self.expected_bw_usage, bw_usage)
|
||||
|
||||
@mock.patch.object(db, 'bw_usage_update')
|
||||
def test_update(self, mock_update):
|
||||
expected_bw_usage1 = self._fake_bw_usage(
|
||||
time=self.expected_bw_usage['last_refreshed'],
|
||||
start_period=self.expected_bw_usage['start_period'],
|
||||
last_ctr_in=42, last_ctr_out=42)
|
||||
|
||||
mock_update.side_effect = [expected_bw_usage1, self.expected_bw_usage]
|
||||
|
||||
bw_usage = bandwidth_usage.BandwidthUsage()
|
||||
bw_usage.create(self.context, 'fake_uuid1', 'fake_mac1',
|
||||
100, 200, 42, 42,
|
||||
start_period=self.expected_bw_usage['start_period'])
|
||||
self._compare(self, expected_bw_usage1, bw_usage)
|
||||
bw_usage.create(self.context, 'fake_uuid1', 'fake_mac1',
|
||||
100, 200, 12345, 67890,
|
||||
start_period=self.expected_bw_usage['start_period'])
|
||||
self._compare(self, self.expected_bw_usage, bw_usage)
|
||||
|
||||
|
||||
class TestBandwidthUsageObject(test_objects._LocalTest,
|
||||
_TestBandwidthUsage):
|
||||
pass
|
||||
|
||||
|
||||
class TestRemoteBandwidthUsageObject(test_objects._RemoteTest,
|
||||
_TestBandwidthUsage):
|
||||
pass
|
@ -933,6 +933,8 @@ object_data = {
|
||||
'AgentList': '1.0-31f07426a729311a42ff7f6246e76e25',
|
||||
'Aggregate': '1.1-f5d477be06150529a9b2d27cc49030b5',
|
||||
'AggregateList': '1.2-4b02a285b8612bfb86a96ff80052fb0a',
|
||||
'BandwidthUsage': '1.0-b59546ee557883434baf46ed33d8fec3',
|
||||
'BandwidthUsageList': '1.0-03dfba3560f9c5a90c474d3d909870e7',
|
||||
'BlockDeviceMapping': '1.2-9968ffe513e7672484b0f528b034cd0f',
|
||||
'BlockDeviceMappingList': '1.3-de607d5ae2f379c75c49a125bb3b4515',
|
||||
'ComputeNode': '1.5-57ce5a07c727ffab6c51723bb8dccbfe',
|
||||
|
Loading…
x
Reference in New Issue
Block a user