virt: Remove 'get_all_bw_counters' API
This one is a little more involved because there are persistent objects and versioned notifications to worry about, neither of which we can remove right now. Change-Id: Ic7c330ee1cccdc44a2a555c16cb6090eecbf6ce1 Signed-off-by: Stephen Finucane <stephenfin@redhat.com>
This commit is contained in:
parent
68bc87876f
commit
9d1683f70f
@ -1,10 +0,0 @@
|
||||
{
|
||||
"nova_object.data": {
|
||||
"network_name": "private",
|
||||
"out_bytes": 0,
|
||||
"in_bytes": 0
|
||||
},
|
||||
"nova_object.name": "BandwidthPayload",
|
||||
"nova_object.namespace": "nova",
|
||||
"nova_object.version": "1.0"
|
||||
}
|
@ -2,9 +2,7 @@
|
||||
"$ref": "InstancePayload.json",
|
||||
"nova_object.data":{
|
||||
"audit_period": {"$ref": "AuditPeriodPayload.json#"},
|
||||
"bandwidth": [
|
||||
{"$ref": "BandwidthPayload.json#"}
|
||||
]
|
||||
"bandwidth": []
|
||||
},
|
||||
"nova_object.name":"InstanceExistsPayload",
|
||||
"nova_object.namespace":"nova",
|
||||
|
@ -542,7 +542,6 @@ class ComputeManager(manager.Manager):
|
||||
self.volume_api = cinder.API()
|
||||
self.image_api = glance.API()
|
||||
self._last_bw_usage_poll = 0.0
|
||||
self._bw_usage_supported = True
|
||||
self.compute_api = compute.API()
|
||||
self.compute_rpcapi = compute_rpcapi.ComputeAPI()
|
||||
self.compute_task_api = conductor.ComputeTaskAPI()
|
||||
@ -9398,86 +9397,6 @@ class ComputeManager(manager.Manager):
|
||||
% (self.host, num_instances, time.time() - start_time))
|
||||
task_log.end_task()
|
||||
|
||||
@periodic_task.periodic_task(spacing=CONF.bandwidth_poll_interval)
|
||||
def _poll_bandwidth_usage(self, context):
|
||||
|
||||
if not self._bw_usage_supported:
|
||||
return
|
||||
|
||||
prev_time, start_time = utils.last_completed_audit_period()
|
||||
|
||||
curr_time = time.time()
|
||||
if (curr_time - self._last_bw_usage_poll >
|
||||
CONF.bandwidth_poll_interval):
|
||||
self._last_bw_usage_poll = curr_time
|
||||
LOG.info("Updating bandwidth usage cache")
|
||||
|
||||
instances = objects.InstanceList.get_by_host(context,
|
||||
self.host,
|
||||
use_slave=True)
|
||||
try:
|
||||
bw_counters = self.driver.get_all_bw_counters(instances)
|
||||
except NotImplementedError:
|
||||
# NOTE(mdragon): Not all hypervisors have bandwidth polling
|
||||
# implemented yet. If they don't it doesn't break anything,
|
||||
# they just don't get the info in the usage events.
|
||||
# NOTE(PhilDay): Record that its not supported so we can
|
||||
# skip fast on future calls rather than waste effort getting
|
||||
# the list of instances.
|
||||
LOG.info("Bandwidth usage not supported by %(driver)s.",
|
||||
{'driver': CONF.compute_driver})
|
||||
self._bw_usage_supported = False
|
||||
return
|
||||
|
||||
refreshed = timeutils.utcnow()
|
||||
for bw_ctr in bw_counters:
|
||||
# Allow switching of greenthreads between queries.
|
||||
greenthread.sleep(0)
|
||||
bw_in = 0
|
||||
bw_out = 0
|
||||
last_ctr_in = None
|
||||
last_ctr_out = None
|
||||
usage = objects.BandwidthUsage.get_by_instance_uuid_and_mac(
|
||||
context, bw_ctr['uuid'], bw_ctr['mac_address'],
|
||||
start_period=start_time, use_slave=True)
|
||||
if usage:
|
||||
bw_in = usage.bw_in
|
||||
bw_out = usage.bw_out
|
||||
last_ctr_in = usage.last_ctr_in
|
||||
last_ctr_out = usage.last_ctr_out
|
||||
else:
|
||||
usage = (objects.BandwidthUsage.
|
||||
get_by_instance_uuid_and_mac(
|
||||
context, bw_ctr['uuid'], bw_ctr['mac_address'],
|
||||
start_period=prev_time, use_slave=True))
|
||||
if usage:
|
||||
last_ctr_in = usage.last_ctr_in
|
||||
last_ctr_out = usage.last_ctr_out
|
||||
|
||||
if last_ctr_in is not None:
|
||||
if bw_ctr['bw_in'] < last_ctr_in:
|
||||
# counter rollover
|
||||
bw_in += bw_ctr['bw_in']
|
||||
else:
|
||||
bw_in += (bw_ctr['bw_in'] - last_ctr_in)
|
||||
|
||||
if last_ctr_out is not None:
|
||||
if bw_ctr['bw_out'] < last_ctr_out:
|
||||
# counter rollover
|
||||
bw_out += bw_ctr['bw_out']
|
||||
else:
|
||||
bw_out += (bw_ctr['bw_out'] - last_ctr_out)
|
||||
|
||||
objects.BandwidthUsage(context=context).create(
|
||||
bw_ctr['uuid'],
|
||||
bw_ctr['mac_address'],
|
||||
bw_in,
|
||||
bw_out,
|
||||
bw_ctr['bw_in'],
|
||||
bw_ctr['bw_out'],
|
||||
start_period=start_time,
|
||||
last_refreshed=refreshed)
|
||||
|
||||
def _get_host_volume_bdms(self, context, use_slave=False):
|
||||
"""Return all block device mappings on a compute host."""
|
||||
compute_host_bdms = []
|
||||
|
@ -356,9 +356,6 @@ def notify_usage_exists(notifier, context, instance_ref, host,
|
||||
|
||||
audit_start, audit_end = notifications.audit_period_bounds(current_period)
|
||||
|
||||
bw = notifications.bandwidth_usage(context, instance_ref, audit_start,
|
||||
ignore_missing_network_data)
|
||||
|
||||
if system_metadata is None:
|
||||
system_metadata = utils.instance_sys_meta(instance_ref)
|
||||
|
||||
@ -367,7 +364,7 @@ def notify_usage_exists(notifier, context, instance_ref, host,
|
||||
|
||||
extra_info = dict(audit_period_beginning=str(audit_start),
|
||||
audit_period_ending=str(audit_end),
|
||||
bandwidth=bw, image_meta=image_meta)
|
||||
bandwidth={}, image_meta=image_meta)
|
||||
|
||||
if extra_usage_info:
|
||||
extra_info.update(extra_usage_info)
|
||||
@ -379,17 +376,11 @@ def notify_usage_exists(notifier, context, instance_ref, host,
|
||||
audit_period_beginning=audit_start,
|
||||
audit_period_ending=audit_end)
|
||||
|
||||
bandwidth = [instance_notification.BandwidthPayload(
|
||||
network_name=label,
|
||||
in_bytes=b['bw_in'],
|
||||
out_bytes=b['bw_out'])
|
||||
for label, b in bw.items()]
|
||||
|
||||
payload = instance_notification.InstanceExistsPayload(
|
||||
context=context,
|
||||
instance=instance_ref,
|
||||
audit_period=audit_period,
|
||||
bandwidth=bandwidth)
|
||||
bandwidth=[])
|
||||
|
||||
notification = instance_notification.InstanceExistsNotification(
|
||||
context=context,
|
||||
|
@ -1004,20 +1004,6 @@ Related options:
|
||||
]
|
||||
|
||||
interval_opts = [
|
||||
cfg.IntOpt('bandwidth_poll_interval',
|
||||
default=600,
|
||||
help="""
|
||||
Interval to pull network bandwidth usage info.
|
||||
|
||||
Not supported on all hypervisors. If a hypervisor doesn't support bandwidth
|
||||
usage, it will not get the info in the usage events.
|
||||
|
||||
Possible values:
|
||||
|
||||
* 0: Will run at the default periodic interval.
|
||||
* Any value < 0: Disables the option.
|
||||
* Any positive integer in seconds.
|
||||
"""),
|
||||
cfg.IntOpt('sync_power_state_interval',
|
||||
default=600,
|
||||
help="""
|
||||
|
@ -1229,6 +1229,8 @@ class AgentBuild(BASE, NovaBase, models.SoftDeleteMixin):
|
||||
md5hash = Column(String(255))
|
||||
|
||||
|
||||
# TODO(stephenfin): Remove this in the W release or later, once we're sure we
|
||||
# won't want it back (it's for a XenAPI-only feature)
|
||||
class BandwidthUsage(BASE, NovaBase, models.SoftDeleteMixin):
|
||||
"""Cache for instance bandwidth usage data pulled from the hypervisor."""
|
||||
__tablename__ = 'bw_usage_cache'
|
||||
|
@ -17,8 +17,8 @@
|
||||
# need to be changed after we moved these function inside the package
|
||||
# Todo(gibi): remove these imports after legacy notifications using these are
|
||||
# transformed to versioned notifications
|
||||
|
||||
from nova.notifications.base import audit_period_bounds # noqa
|
||||
from nova.notifications.base import bandwidth_usage # noqa
|
||||
from nova.notifications.base import image_meta # noqa
|
||||
from nova.notifications.base import info_from_instance # noqa
|
||||
from nova.notifications.base import send_update # noqa
|
||||
|
@ -29,12 +29,8 @@ import nova.conf
|
||||
import nova.context
|
||||
from nova import exception
|
||||
from nova.image import glance
|
||||
from nova.network import model as network_model
|
||||
from nova.network import neutron
|
||||
from nova.notifications.objects import base as notification_base
|
||||
from nova.notifications.objects import instance as instance_notification
|
||||
from nova import objects
|
||||
from nova.objects import base as obj_base
|
||||
from nova.objects import fields
|
||||
from nova import rpc
|
||||
from nova import utils
|
||||
@ -194,8 +190,8 @@ def send_instance_update_notification(context, instance, old_vm_state=None,
|
||||
payload["audit_period_ending"] = null_safe_isotime(audit_end)
|
||||
|
||||
# add bw usage info:
|
||||
bw = bandwidth_usage(context, instance, audit_start)
|
||||
payload["bandwidth"] = bw
|
||||
# TODO(stephenfin): Remove this, the feature is dead
|
||||
payload["bandwidth"] = {}
|
||||
|
||||
# add old display name if it is changed
|
||||
if old_display_name:
|
||||
@ -223,14 +219,11 @@ def _send_versioned_instance_update(context, instance, payload, host, service):
|
||||
new_task_state=payload.get('new_task_state'))
|
||||
|
||||
audit_period = instance_notification.AuditPeriodPayload(
|
||||
audit_period_beginning=payload.get('audit_period_beginning'),
|
||||
audit_period_ending=payload.get('audit_period_ending'))
|
||||
audit_period_beginning=payload.get('audit_period_beginning'),
|
||||
audit_period_ending=payload.get('audit_period_ending'))
|
||||
|
||||
bandwidth = [instance_notification.BandwidthPayload(
|
||||
network_name=label,
|
||||
in_bytes=bw['bw_in'],
|
||||
out_bytes=bw['bw_out'])
|
||||
for label, bw in payload['bandwidth'].items()]
|
||||
# TODO(stephenfin): Remove this, the feature is dead
|
||||
bandwidth = []
|
||||
|
||||
versioned_payload = instance_notification.InstanceUpdatePayload(
|
||||
context=context,
|
||||
@ -271,62 +264,6 @@ def audit_period_bounds(current_period=False):
|
||||
return (audit_start, audit_end)
|
||||
|
||||
|
||||
def bandwidth_usage(context, instance_ref, audit_start,
|
||||
ignore_missing_network_data=True):
|
||||
"""Get bandwidth usage information for the instance for the
|
||||
specified audit period.
|
||||
"""
|
||||
admin_context = context.elevated(read_deleted='yes')
|
||||
|
||||
def _get_nwinfo_old_skool():
|
||||
"""Support for getting network info without objects."""
|
||||
if (instance_ref.get('info_cache') and
|
||||
instance_ref['info_cache'].get('network_info') is not None):
|
||||
cached_info = instance_ref['info_cache']['network_info']
|
||||
if isinstance(cached_info, network_model.NetworkInfo):
|
||||
return cached_info
|
||||
return network_model.NetworkInfo.hydrate(cached_info)
|
||||
try:
|
||||
return neutron.API().get_instance_nw_info(admin_context,
|
||||
instance_ref)
|
||||
except Exception:
|
||||
try:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.exception('Failed to get nw_info',
|
||||
instance=instance_ref)
|
||||
except Exception:
|
||||
if ignore_missing_network_data:
|
||||
return
|
||||
raise
|
||||
|
||||
# FIXME(comstud): Temporary as we transition to objects.
|
||||
if isinstance(instance_ref, obj_base.NovaObject):
|
||||
nw_info = instance_ref.info_cache.network_info
|
||||
if nw_info is None:
|
||||
nw_info = network_model.NetworkInfo()
|
||||
else:
|
||||
nw_info = _get_nwinfo_old_skool()
|
||||
|
||||
macs = [vif['address'] for vif in nw_info]
|
||||
uuids = [instance_ref["uuid"]]
|
||||
|
||||
bw_usages = objects.BandwidthUsageList.get_by_uuids(admin_context, uuids,
|
||||
audit_start)
|
||||
bw = {}
|
||||
|
||||
for b in bw_usages:
|
||||
if b.mac in macs:
|
||||
label = 'net-name-not-found-%s' % b.mac
|
||||
for vif in nw_info:
|
||||
if vif['address'] == b.mac:
|
||||
label = vif['network']['label']
|
||||
break
|
||||
|
||||
bw[label] = dict(bw_in=b.bw_in, bw_out=b.bw_out)
|
||||
|
||||
return bw
|
||||
|
||||
|
||||
def image_meta(system_metadata):
|
||||
"""Format image metadata for use in notifications from the instance
|
||||
system metadata.
|
||||
|
@ -300,6 +300,7 @@ class InstanceUpdatePayload(InstancePayload):
|
||||
fields = {
|
||||
'state_update': fields.ObjectField('InstanceStateUpdatePayload'),
|
||||
'audit_period': fields.ObjectField('AuditPeriodPayload'),
|
||||
# TODO(stephenfin): Remove this field in 2.0
|
||||
'bandwidth': fields.ListOfObjectsField('BandwidthPayload'),
|
||||
'old_display_name': fields.StringField(nullable=True),
|
||||
'tags': fields.ListOfStringsField(),
|
||||
@ -411,6 +412,7 @@ class IpPayload(base.NotificationPayloadBase):
|
||||
return ips
|
||||
|
||||
|
||||
# TODO(stephenfin): Drop this object
|
||||
@nova_base.NovaObjectRegistry.register_notification
|
||||
class BandwidthPayload(base.NotificationPayloadBase):
|
||||
# Version 1.0: Initial version
|
||||
@ -722,6 +724,7 @@ class InstanceExistsPayload(InstancePayload):
|
||||
VERSION = '1.2'
|
||||
fields = {
|
||||
'audit_period': fields.ObjectField('AuditPeriodPayload'),
|
||||
# TODO(stephenfin): Remove this field in version 2.0
|
||||
'bandwidth': fields.ListOfObjectsField('BandwidthPayload'),
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,8 @@ from nova.objects import base
|
||||
from nova.objects import fields
|
||||
|
||||
|
||||
# TODO(stephenfin): Remove after W, once we no longer need to worry about the
|
||||
# versioned notification framework using this
|
||||
@base.NovaObjectRegistry.register
|
||||
class BandwidthUsage(base.NovaPersistentObject, base.NovaObject):
|
||||
# Version 1.0: Initial version
|
||||
@ -60,7 +62,6 @@ class BandwidthUsage(base.NovaPersistentObject, base.NovaObject):
|
||||
if db_bw_usage:
|
||||
return cls._from_db_object(context, cls(), db_bw_usage)
|
||||
|
||||
# TODO(stephenfin): Remove 'update_cells' in version 2.0 of the object
|
||||
@base.serialize_args
|
||||
@base.remotable
|
||||
def create(self, uuid, mac, bw_in, bw_out, last_ctr_in,
|
||||
@ -73,6 +74,8 @@ class BandwidthUsage(base.NovaPersistentObject, base.NovaObject):
|
||||
self._from_db_object(self._context, self, db_bw_usage)
|
||||
|
||||
|
||||
# TODO(stephenfin): Remove after W, once we no longer need to worry about the
|
||||
# versioned notification framework using this
|
||||
@base.NovaObjectRegistry.register
|
||||
class BandwidthUsageList(base.ObjectListBase, base.NovaObject):
|
||||
# Version 1.0: Initial version
|
||||
|
@ -14,7 +14,6 @@ import time
|
||||
|
||||
import mock
|
||||
|
||||
from nova import context
|
||||
from nova import exception
|
||||
from nova.tests import fixtures
|
||||
from nova.tests.functional.api import client
|
||||
@ -503,10 +502,6 @@ class TestInstanceNotificationSample(
|
||||
|
||||
self._attach_volume_to_server(server, self.cinder.SWAP_OLD_VOL)
|
||||
|
||||
# Let's generate some bandwidth usage data.
|
||||
# Just call the periodic task directly for simplicity
|
||||
self.compute.manager._poll_bandwidth_usage(context.get_admin_context())
|
||||
|
||||
fake_notifier.reset()
|
||||
|
||||
post = {
|
||||
@ -671,10 +666,6 @@ class TestInstanceNotificationSample(
|
||||
|
||||
fake_notifier.reset()
|
||||
|
||||
# Let's generate some bandwidth usage data.
|
||||
# Just call the periodic task directly for simplicity
|
||||
self.compute.manager._poll_bandwidth_usage(context.get_admin_context())
|
||||
|
||||
self._delete_server(server)
|
||||
|
||||
instance_updates = self._get_notifications('instance.update')
|
||||
@ -688,14 +679,7 @@ class TestInstanceNotificationSample(
|
||||
'state_update.old_state': 'active',
|
||||
'state': 'active',
|
||||
'task_state': 'deleting',
|
||||
'bandwidth': [
|
||||
{'nova_object.namespace': 'nova',
|
||||
'nova_object.name': 'BandwidthPayload',
|
||||
'nova_object.data':
|
||||
{'network_name': 'private',
|
||||
'out_bytes': 0,
|
||||
'in_bytes': 0},
|
||||
'nova_object.version': '1.0'}],
|
||||
'bandwidth': [],
|
||||
'tags': ["tag1"],
|
||||
'block_devices': [{
|
||||
"nova_object.data": {
|
||||
|
@ -22,11 +22,9 @@ import fixtures as std_fixtures
|
||||
from itertools import chain
|
||||
import operator
|
||||
import sys
|
||||
import time
|
||||
|
||||
import ddt
|
||||
|
||||
from castellan import key_manager
|
||||
import ddt
|
||||
import mock
|
||||
from neutronclient.common import exceptions as neutron_exceptions
|
||||
from oslo_log import log as logging
|
||||
@ -753,39 +751,6 @@ class ComputeVolumeTestCase(BaseTestCase):
|
||||
def test_boot_image_no_metadata(self):
|
||||
self.test_boot_image_metadata(metadata=False)
|
||||
|
||||
@mock.patch.object(time, 'time')
|
||||
@mock.patch.object(objects.InstanceList, 'get_by_host')
|
||||
@mock.patch.object(utils, 'last_completed_audit_period')
|
||||
@mock.patch.object(fake.FakeDriver, 'get_all_bw_counters')
|
||||
def test_poll_bandwidth_usage_not_implemented(self, mock_get_counter,
|
||||
mock_last, mock_get_host, mock_time):
|
||||
ctxt = context.get_admin_context()
|
||||
|
||||
# Following methods will be called
|
||||
# Note - time called two more times from Log
|
||||
mock_last.return_value = (0, 0)
|
||||
mock_time.side_effect = (10, 20, 21)
|
||||
|
||||
mock_get_host.return_value = []
|
||||
mock_get_counter.side_effect = NotImplementedError
|
||||
|
||||
self.flags(bandwidth_poll_interval=1)
|
||||
# The first call will catch a NotImplementedError,
|
||||
# then LOG.info something below:
|
||||
self.compute._poll_bandwidth_usage(ctxt)
|
||||
self.assertIn('Bandwidth usage not supported '
|
||||
'by %s' % CONF.compute_driver,
|
||||
self.stdlog.logger.output)
|
||||
|
||||
# A second call won't call the stubs again as the bandwidth
|
||||
# poll is now disabled
|
||||
self.compute._poll_bandwidth_usage(ctxt)
|
||||
|
||||
mock_get_counter.assert_called_once_with([])
|
||||
mock_last.assert_called_once_with()
|
||||
mock_get_host.assert_called_once_with(ctxt, 'fake-mini',
|
||||
use_slave=True)
|
||||
|
||||
@mock.patch.object(objects.InstanceList, 'get_by_host')
|
||||
@mock.patch.object(objects.BlockDeviceMappingList,
|
||||
'get_by_instance_uuid')
|
||||
|
@ -73,7 +73,6 @@ from nova.tests.unit import fake_notifier
|
||||
from nova.tests.unit.objects import test_instance_fault
|
||||
from nova.tests.unit.objects import test_instance_info_cache
|
||||
from nova.tests.unit.objects import test_instance_numa
|
||||
from nova import utils
|
||||
from nova.virt.block_device import DriverVolumeBlockDevice as driver_bdm_volume
|
||||
from nova.virt import driver as virt_driver
|
||||
from nova.virt import event as virtevent
|
||||
@ -5536,41 +5535,6 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase,
|
||||
self.assertIn('Trusted image certificates provided on host',
|
||||
six.text_type(ex))
|
||||
|
||||
@mock.patch.object(utils, 'last_completed_audit_period',
|
||||
return_value=(0, 0))
|
||||
@mock.patch.object(time, 'time', side_effect=[10, 20, 21])
|
||||
@mock.patch.object(objects.InstanceList, 'get_by_host', return_value=[])
|
||||
@mock.patch.object(objects.BandwidthUsage, 'get_by_instance_uuid_and_mac')
|
||||
@mock.patch.object(db, 'bw_usage_update')
|
||||
def test_poll_bandwidth_usage(self, bw_usage_update, get_by_uuid_mac,
|
||||
get_by_host, time, last_completed_audit):
|
||||
bw_counters = [{'uuid': uuids.instance, 'mac_address': 'fake-mac',
|
||||
'bw_in': 1, 'bw_out': 2}]
|
||||
usage = objects.BandwidthUsage()
|
||||
usage.bw_in = 3
|
||||
usage.bw_out = 4
|
||||
usage.last_ctr_in = 0
|
||||
usage.last_ctr_out = 0
|
||||
self.flags(bandwidth_poll_interval=1)
|
||||
get_by_uuid_mac.return_value = usage
|
||||
_time = timeutils.utcnow()
|
||||
bw_usage_update.return_value = {'uuid': uuids.instance, 'mac': '',
|
||||
'start_period': _time, 'last_refreshed': _time, 'bw_in': 0,
|
||||
'bw_out': 0, 'last_ctr_in': 0, 'last_ctr_out': 0, 'deleted': 0,
|
||||
'created_at': _time, 'updated_at': _time, 'deleted_at': _time}
|
||||
with mock.patch.object(self.compute.driver,
|
||||
'get_all_bw_counters', return_value=bw_counters):
|
||||
self.compute._poll_bandwidth_usage(self.context)
|
||||
get_by_uuid_mac.assert_called_once_with(self.context,
|
||||
uuids.instance, 'fake-mac',
|
||||
start_period=0, use_slave=True)
|
||||
# NOTE(sdague): bw_usage_update happens at some time in
|
||||
# the future, so what last_refreshed is irrelevant.
|
||||
bw_usage_update.assert_called_once_with(self.context,
|
||||
uuids.instance,
|
||||
'fake-mac', 0, 4, 6, 1, 2,
|
||||
last_refreshed=mock.ANY)
|
||||
|
||||
def test_reverts_task_state_instance_not_found(self):
|
||||
# Tests that the reverts_task_state decorator in the compute manager
|
||||
# will not trace when an InstanceNotFound is raised.
|
||||
|
@ -5817,200 +5817,6 @@ class CertificateTestCase(test.TestCase, ModelsObjectComparatorMixin):
|
||||
self._assertEqualObjects(self.created[1], cert[0])
|
||||
|
||||
|
||||
class BwUsageTestCase(test.TestCase, ModelsObjectComparatorMixin):
|
||||
|
||||
_ignored_keys = ['id', 'deleted', 'deleted_at', 'created_at', 'updated_at']
|
||||
|
||||
def setUp(self):
|
||||
super(BwUsageTestCase, self).setUp()
|
||||
self.ctxt = context.get_admin_context()
|
||||
self.useFixture(test.TimeOverride())
|
||||
|
||||
def test_bw_usage_get_by_uuids(self):
|
||||
now = timeutils.utcnow()
|
||||
start_period = now - datetime.timedelta(seconds=10)
|
||||
start_period_str = start_period.isoformat()
|
||||
uuid3_refreshed = now - datetime.timedelta(seconds=5)
|
||||
uuid3_refreshed_str = uuid3_refreshed.isoformat()
|
||||
|
||||
expected_bw_usages = {
|
||||
'fake_uuid1': {'uuid': 'fake_uuid1',
|
||||
'mac': 'fake_mac1',
|
||||
'start_period': start_period,
|
||||
'bw_in': 100,
|
||||
'bw_out': 200,
|
||||
'last_ctr_in': 12345,
|
||||
'last_ctr_out': 67890,
|
||||
'last_refreshed': now},
|
||||
'fake_uuid2': {'uuid': 'fake_uuid2',
|
||||
'mac': 'fake_mac2',
|
||||
'start_period': start_period,
|
||||
'bw_in': 200,
|
||||
'bw_out': 300,
|
||||
'last_ctr_in': 22345,
|
||||
'last_ctr_out': 77890,
|
||||
'last_refreshed': now},
|
||||
'fake_uuid3': {'uuid': 'fake_uuid3',
|
||||
'mac': 'fake_mac3',
|
||||
'start_period': start_period,
|
||||
'bw_in': 400,
|
||||
'bw_out': 500,
|
||||
'last_ctr_in': 32345,
|
||||
'last_ctr_out': 87890,
|
||||
'last_refreshed': uuid3_refreshed}
|
||||
}
|
||||
|
||||
bw_usages = db.bw_usage_get_by_uuids(self.ctxt,
|
||||
['fake_uuid1', 'fake_uuid2'], start_period_str)
|
||||
# No matches
|
||||
self.assertEqual(len(bw_usages), 0)
|
||||
|
||||
# Add 3 entries
|
||||
db.bw_usage_update(self.ctxt, 'fake_uuid1',
|
||||
'fake_mac1', start_period_str,
|
||||
100, 200, 12345, 67890)
|
||||
db.bw_usage_update(self.ctxt, 'fake_uuid2',
|
||||
'fake_mac2', start_period_str,
|
||||
100, 200, 42, 42)
|
||||
# Test explicit refreshed time
|
||||
db.bw_usage_update(self.ctxt, 'fake_uuid3',
|
||||
'fake_mac3', start_period_str,
|
||||
400, 500, 32345, 87890,
|
||||
last_refreshed=uuid3_refreshed_str)
|
||||
# Update 2nd entry
|
||||
db.bw_usage_update(self.ctxt, 'fake_uuid2',
|
||||
'fake_mac2', start_period_str,
|
||||
200, 300, 22345, 77890)
|
||||
|
||||
bw_usages = db.bw_usage_get_by_uuids(self.ctxt,
|
||||
['fake_uuid1', 'fake_uuid2', 'fake_uuid3'], start_period_str)
|
||||
self.assertEqual(len(bw_usages), 3)
|
||||
for usage in bw_usages:
|
||||
self._assertEqualObjects(expected_bw_usages[usage['uuid']], usage,
|
||||
ignored_keys=self._ignored_keys)
|
||||
|
||||
def _test_bw_usage_update(self, **expected_bw_usage):
|
||||
bw_usage = db.bw_usage_update(self.ctxt, **expected_bw_usage)
|
||||
self._assertEqualObjects(expected_bw_usage, bw_usage,
|
||||
ignored_keys=self._ignored_keys)
|
||||
|
||||
uuid = expected_bw_usage['uuid']
|
||||
mac = expected_bw_usage['mac']
|
||||
start_period = expected_bw_usage['start_period']
|
||||
bw_usage = db.bw_usage_get(self.ctxt, uuid, start_period, mac)
|
||||
self._assertEqualObjects(expected_bw_usage, bw_usage,
|
||||
ignored_keys=self._ignored_keys)
|
||||
|
||||
def _create_bw_usage(self, context, uuid, mac, start_period, bw_in, bw_out,
|
||||
last_ctr_in, last_ctr_out, id, last_refreshed=None):
|
||||
with sqlalchemy_api.get_context_manager(context).writer.using(context):
|
||||
bwusage = models.BandwidthUsage()
|
||||
bwusage.start_period = start_period
|
||||
bwusage.uuid = uuid
|
||||
bwusage.mac = mac
|
||||
bwusage.last_refreshed = last_refreshed
|
||||
bwusage.bw_in = bw_in
|
||||
bwusage.bw_out = bw_out
|
||||
bwusage.last_ctr_in = last_ctr_in
|
||||
bwusage.last_ctr_out = last_ctr_out
|
||||
bwusage.id = id
|
||||
bwusage.save(context.session)
|
||||
|
||||
def test_bw_usage_update_exactly_one_record(self):
|
||||
now = timeutils.utcnow()
|
||||
start_period = now - datetime.timedelta(seconds=10)
|
||||
uuid = 'fake_uuid'
|
||||
|
||||
# create two equal bw_usages with IDs 1 and 2
|
||||
for id in range(1, 3):
|
||||
bw_usage = {'uuid': uuid,
|
||||
'mac': 'fake_mac',
|
||||
'start_period': start_period,
|
||||
'bw_in': 100,
|
||||
'bw_out': 200,
|
||||
'last_ctr_in': 12345,
|
||||
'last_ctr_out': 67890,
|
||||
'last_refreshed': now,
|
||||
'id': id}
|
||||
self._create_bw_usage(self.ctxt, **bw_usage)
|
||||
|
||||
# check that we have two equal bw_usages
|
||||
self.assertEqual(
|
||||
2, len(db.bw_usage_get_by_uuids(self.ctxt, [uuid], start_period)))
|
||||
|
||||
# update 'last_ctr_in' field in one bw_usage
|
||||
updated_bw_usage = {'uuid': uuid,
|
||||
'mac': 'fake_mac',
|
||||
'start_period': start_period,
|
||||
'bw_in': 100,
|
||||
'bw_out': 200,
|
||||
'last_ctr_in': 54321,
|
||||
'last_ctr_out': 67890,
|
||||
'last_refreshed': now}
|
||||
result = db.bw_usage_update(self.ctxt, **updated_bw_usage)
|
||||
|
||||
# check that only bw_usage with ID 1 was updated
|
||||
self.assertEqual(1, result['id'])
|
||||
self._assertEqualObjects(updated_bw_usage, result,
|
||||
ignored_keys=self._ignored_keys)
|
||||
|
||||
def test_bw_usage_get(self):
|
||||
now = timeutils.utcnow()
|
||||
start_period = now - datetime.timedelta(seconds=10)
|
||||
start_period_str = start_period.isoformat()
|
||||
|
||||
expected_bw_usage = {'uuid': 'fake_uuid1',
|
||||
'mac': 'fake_mac1',
|
||||
'start_period': start_period,
|
||||
'bw_in': 100,
|
||||
'bw_out': 200,
|
||||
'last_ctr_in': 12345,
|
||||
'last_ctr_out': 67890,
|
||||
'last_refreshed': now}
|
||||
|
||||
bw_usage = db.bw_usage_get(self.ctxt, 'fake_uuid1', start_period_str,
|
||||
'fake_mac1')
|
||||
self.assertIsNone(bw_usage)
|
||||
self._test_bw_usage_update(**expected_bw_usage)
|
||||
|
||||
def test_bw_usage_update_new(self):
|
||||
now = timeutils.utcnow()
|
||||
start_period = now - datetime.timedelta(seconds=10)
|
||||
|
||||
expected_bw_usage = {'uuid': 'fake_uuid1',
|
||||
'mac': 'fake_mac1',
|
||||
'start_period': start_period,
|
||||
'bw_in': 100,
|
||||
'bw_out': 200,
|
||||
'last_ctr_in': 12345,
|
||||
'last_ctr_out': 67890,
|
||||
'last_refreshed': now}
|
||||
|
||||
self._test_bw_usage_update(**expected_bw_usage)
|
||||
|
||||
def test_bw_usage_update_existing(self):
|
||||
now = timeutils.utcnow()
|
||||
start_period = now - datetime.timedelta(seconds=10)
|
||||
|
||||
expected_bw_usage = {'uuid': 'fake_uuid1',
|
||||
'mac': 'fake_mac1',
|
||||
'start_period': start_period,
|
||||
'bw_in': 100,
|
||||
'bw_out': 200,
|
||||
'last_ctr_in': 12345,
|
||||
'last_ctr_out': 67890,
|
||||
'last_refreshed': now}
|
||||
|
||||
self._test_bw_usage_update(**expected_bw_usage)
|
||||
|
||||
expected_bw_usage['bw_in'] = 300
|
||||
expected_bw_usage['bw_out'] = 400
|
||||
expected_bw_usage['last_ctr_in'] = 23456
|
||||
expected_bw_usage['last_ctr_out'] = 78901
|
||||
|
||||
self._test_bw_usage_update(**expected_bw_usage)
|
||||
|
||||
|
||||
class Ec2TestCase(test.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
|
@ -63,14 +63,12 @@ class TestSendInstanceUpdateNotification(test.NoDBTestCase):
|
||||
mock.sentinel.host,
|
||||
mock.sentinel.service)
|
||||
|
||||
@mock.patch.object(base, 'bandwidth_usage')
|
||||
@mock.patch.object(base, '_compute_states_payload')
|
||||
@mock.patch('nova.rpc.get_notifier')
|
||||
@mock.patch.object(base, 'info_from_instance')
|
||||
def test_send_legacy_instance_update_notification(self, mock_info,
|
||||
mock_get_notifier,
|
||||
mock_states,
|
||||
mock_bw):
|
||||
def test_send_legacy_instance_update_notification(
|
||||
self, mock_info, mock_get_notifier, mock_states,
|
||||
):
|
||||
"""Tests the case that versioned notifications are disabled and
|
||||
assert that this does not prevent sending the unversioned
|
||||
instance.update notification.
|
||||
@ -132,25 +130,3 @@ class TestSendInstanceUpdateNotification(test.NoDBTestCase):
|
||||
populate_image_ref_url=False)
|
||||
|
||||
mock_gen_image_url.assert_not_called()
|
||||
|
||||
|
||||
class TestBandwidthUsage(test.NoDBTestCase):
|
||||
@mock.patch('nova.context.RequestContext.elevated')
|
||||
@mock.patch('nova.network.neutron.API')
|
||||
@mock.patch('nova.objects.BandwidthUsageList.get_by_uuids')
|
||||
def test_context_elevated(self, mock_get_bw_usage, mock_nw_api,
|
||||
mock_elevated):
|
||||
context = nova_context.RequestContext('fake', 'fake')
|
||||
# We need this to not be a NovaObject so the old school
|
||||
# get_instance_nw_info will run.
|
||||
instance = {'uuid': uuids.instance}
|
||||
audit_start = 'fake'
|
||||
|
||||
base.bandwidth_usage(context, instance, audit_start)
|
||||
|
||||
network_api = mock_nw_api.return_value
|
||||
network_api.get_instance_nw_info.assert_called_once_with(
|
||||
mock_elevated.return_value, instance)
|
||||
mock_get_bw_usage.assert_called_once_with(
|
||||
mock_elevated.return_value, [uuids.instance], audit_start)
|
||||
mock_elevated.assert_called_once_with(read_deleted='yes')
|
||||
|
@ -198,21 +198,7 @@ class NotificationsTestCase(test.TestCase):
|
||||
self.assertEqual(0, len(fake_notifier.NOTIFICATIONS))
|
||||
self.assertEqual(0, len(fake_notifier.VERSIONED_NOTIFICATIONS))
|
||||
|
||||
def get_fake_bandwidth(self):
|
||||
usage = objects.BandwidthUsage(context=self.context)
|
||||
usage.create(
|
||||
self.instance.uuid,
|
||||
mac='DE:AD:BE:EF:00:01',
|
||||
bw_in=1,
|
||||
bw_out=2,
|
||||
last_ctr_in=0,
|
||||
last_ctr_out=0,
|
||||
start_period='2012-10-29T13:42:11Z')
|
||||
return usage
|
||||
|
||||
@mock.patch.object(objects.BandwidthUsageList, 'get_by_uuids')
|
||||
def test_vm_update_with_states(self, mock_bandwidth_list):
|
||||
mock_bandwidth_list.return_value = [self.get_fake_bandwidth()]
|
||||
def test_vm_update_with_states(self):
|
||||
fake_net_info = fake_network.fake_get_instance_nw_info(self)
|
||||
self.instance.info_cache.network_info = fake_net_info
|
||||
|
||||
@ -279,17 +265,11 @@ class NotificationsTestCase(test.TestCase):
|
||||
self.assertEqual(actual_ip['address'], expected_ip['address'])
|
||||
|
||||
bandwidth = payload['bandwidth']
|
||||
self.assertEqual(len(bandwidth), 1)
|
||||
bandwidth = bandwidth[0]['nova_object.data']
|
||||
self.assertEqual(bandwidth['in_bytes'], 1)
|
||||
self.assertEqual(bandwidth['out_bytes'], 2)
|
||||
self.assertEqual(bandwidth['network_name'], 'test1')
|
||||
self.assertEqual(0, len(bandwidth))
|
||||
|
||||
@mock.patch.object(objects.BandwidthUsageList, 'get_by_uuids')
|
||||
def test_task_update_with_states(self, mock_bandwidth_list):
|
||||
def test_task_update_with_states(self):
|
||||
self.flags(notify_on_state_change="vm_and_task_state",
|
||||
group='notifications')
|
||||
mock_bandwidth_list.return_value = [self.get_fake_bandwidth()]
|
||||
fake_net_info = fake_network.fake_get_instance_nw_info(self)
|
||||
self.instance.info_cache.network_info = fake_net_info
|
||||
|
||||
|
@ -556,16 +556,6 @@ class ComputeDriver(object):
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
# TODO(stephenfin): This was only implemented (properly) for XenAPI and
|
||||
# should be removed.
|
||||
def get_all_bw_counters(self, instances):
|
||||
"""Return bandwidth usage counters for each interface on each
|
||||
running VM.
|
||||
|
||||
:param instances: nova.objects.instance.InstanceList
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def get_all_volume_usage(self, context, compute_host_bdms):
|
||||
"""Return usage info for volumes attached to vms on
|
||||
a given host.-
|
||||
|
@ -420,18 +420,6 @@ class FakeDriver(driver.ComputeDriver):
|
||||
maximum=524288, used=0)
|
||||
return diags
|
||||
|
||||
def get_all_bw_counters(self, instances):
|
||||
"""Return bandwidth usage counters for each interface on each
|
||||
running VM.
|
||||
"""
|
||||
bw = []
|
||||
for instance in instances:
|
||||
bw.append({'uuid': instance.uuid,
|
||||
'mac_address': 'fa:16:3e:4c:2c:30',
|
||||
'bw_in': 0,
|
||||
'bw_out': 0})
|
||||
return bw
|
||||
|
||||
def get_all_volume_usage(self, context, compute_host_bdms):
|
||||
"""Return usage info for volumes attached to vms on
|
||||
a given host.
|
||||
|
@ -61,3 +61,4 @@ upgrade:
|
||||
* ``[xenserver] ovs_integration_bridge``
|
||||
* ``[xenserver] use_join_force``
|
||||
* ``[xenserver] console_public_hostname``
|
||||
* ``[DEFAULT] bandwidth_poll_interval``
|
||||
|
Loading…
Reference in New Issue
Block a user