Hyper-V: replaces in-tree hyper-v utils usage with os_win

os-win is a library containing Windows / Hyper-V related code.
It contains utils modules that are used by nova, cinder,
networking_hyperv, os-brick. It also contains Hyper-V metrics
related utils, which can be used in ceilometer.

Adds os-win to requirements.txt.
Replaces the current usage of *Utils classes in the
Hyper-V Inspector with the equivalent *Utils classes
from os-win.

Adds decorators to the HyperVInspector methods that prevent
os-win specific exceptions to leak outside the inspector.

Depends-On: Ia937399c999d7293799a864a322323e3d2efc123
Depends-On: I1256b632be7aa90561338b595b9406c30f406c7c

Change-Id: Ic637e2a9c929cac88b1cb99f5b55dd70c4f84c47
This commit is contained in:
Claudiu Belu 2016-02-16 02:29:18 +02:00
parent 73e141b4cb
commit 235556a5b2
5 changed files with 125 additions and 546 deletions

View File

@ -13,27 +13,91 @@
# under the License.
"""Implementation of Inspector abstraction for Hyper-V"""
import collections
import functools
import sys
from os_win import exceptions as os_win_exc
from os_win import utilsfactory
from oslo_utils import units
import six
from ceilometer.compute.pollsters import util
from ceilometer.compute.virt.hyperv import utilsv2
from ceilometer.compute.virt import inspector as virt_inspector
def convert_exceptions(function, exception_map):
expected_exceptions = tuple(exception_map.keys())
@functools.wraps(function)
def wrapper(*args, **kwargs):
try:
return function(*args, **kwargs)
except expected_exceptions as ex:
# exception might be a subclass of an expected exception.
for expected in expected_exceptions:
if isinstance(ex, expected):
raised_exception = exception_map[expected]
break
exc_info = sys.exc_info()
# NOTE(claudiub): Python 3 raises the exception object given as
# the second argument in six.reraise.
# The original message will be maintained by passing the original
# exception.
exc = raised_exception(six.text_type(exc_info[1]))
six.reraise(raised_exception, exc, exc_info[2])
return wrapper
def decorate_all_methods(decorator, *args, **kwargs):
def decorate(cls):
for attr in cls.__dict__:
class_member = getattr(cls, attr)
if callable(class_member):
setattr(cls, attr, decorator(class_member, *args, **kwargs))
return cls
return decorate
exception_conversion_map = collections.OrderedDict([
# NOTE(claudiub): order should be from the most specialized exception type
# to the most generic exception type.
# (expected_exception, converted_exception)
(os_win_exc.NotFound, virt_inspector.InstanceNotFoundException),
(os_win_exc.OSWinException, virt_inspector.InspectorException),
])
# NOTE(claudiub): the purpose of the decorator below is to prevent any
# os_win exceptions (subclasses of OSWinException) to leak outside of the
# HyperVInspector.
@decorate_all_methods(convert_exceptions, exception_conversion_map)
class HyperVInspector(virt_inspector.Inspector):
def __init__(self):
super(HyperVInspector, self).__init__()
self._utils = utilsv2.UtilsV2()
self._utils = utilsfactory.get_metricsutils()
self._host_max_cpu_clock = self._compute_host_max_cpu_clock()
def _compute_host_max_cpu_clock(self):
hostutils = utilsfactory.get_hostutils()
# host's number of CPUs and CPU clock speed will not change.
cpu_info = hostutils.get_cpus_info()
host_cpu_count = len(cpu_info)
host_cpu_clock = cpu_info[0]['MaxClockSpeed']
return float(host_cpu_clock * host_cpu_count)
def inspect_cpus(self, instance):
instance_name = util.instance_name(instance)
(cpu_clock_used,
cpu_count, uptime) = self._utils.get_cpu_metrics(instance_name)
host_cpu_clock, host_cpu_count = self._utils.get_host_cpu_info()
cpu_percent_used = (cpu_clock_used /
float(host_cpu_clock * cpu_count))
cpu_percent_used = cpu_clock_used / self._host_max_cpu_clock
# Nanoseconds
cpu_time = (int(uptime * cpu_percent_used) * units.k)

View File

@ -1,247 +0,0 @@
# Copyright 2013 Cloudbase Solutions Srl
#
# 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.
"""
Utility class for VM related operations.
Based on the "root/virtualization/v2" namespace available starting with
Hyper-V Server / Windows Server 2012.
"""
import sys
if sys.platform == 'win32':
import wmi
from ceilometer.compute.virt import inspector
from ceilometer.i18n import _
class HyperVException(inspector.InspectorException):
pass
class UtilsV2(object):
_VIRTUAL_SYSTEM_TYPE_REALIZED = 'Microsoft:Hyper-V:System:Realized'
_PROC_SETTING = 'Msvm_ProcessorSettingData'
_MEMORY_SETTING = "Msvm_MemorySettingData"
_SYNTH_ETH_PORT = 'Msvm_SyntheticEthernetPortSettingData'
_ETH_PORT_ALLOC = 'Msvm_EthernetPortAllocationSettingData'
_PORT_ACL_SET_DATA = 'Msvm_EthernetSwitchPortAclSettingData'
_STORAGE_ALLOC = 'Msvm_StorageAllocationSettingData'
_VS_SETTING_DATA = 'Msvm_VirtualSystemSettingData'
_METRICS_ME = 'Msvm_MetricForME'
_BASE_METRICS_VALUE = 'Msvm_BaseMetricValue'
_CPU_METRIC_NAME = 'Aggregated Average CPU Utilization'
_MEMORY_METRIC_NAME = 'Aggregated Average Memory Utilization'
_NET_IN_METRIC_NAME = 'Filtered Incoming Network Traffic'
_NET_OUT_METRIC_NAME = 'Filtered Outgoing Network Traffic'
# Disk metrics are supported from Hyper-V 2012 R2
_DISK_RD_METRIC_NAME = 'Disk Data Read'
_DISK_WR_METRIC_NAME = 'Disk Data Written'
_DISK_LATENCY_METRIC_NAME = 'Average Disk Latency'
_DISK_IOPS_METRIC_NAME = 'Average Normalized Disk Throughput'
def __init__(self, host='.'):
if sys.platform == 'win32':
self._init_hyperv_wmi_conn(host)
self._init_cimv2_wmi_conn(host)
self._host_cpu_info = None
def _init_hyperv_wmi_conn(self, host):
self._conn = wmi.WMI(moniker='//%s/root/virtualization/v2' % host)
def _init_cimv2_wmi_conn(self, host):
self._conn_cimv2 = wmi.WMI(moniker='//%s/root/cimv2' % host)
def get_host_cpu_info(self):
if not self._host_cpu_info:
host_cpus = self._conn_cimv2.Win32_Processor()
self._host_cpu_info = (host_cpus[0].MaxClockSpeed, len(host_cpus))
return self._host_cpu_info
def get_all_vms(self):
vms = [(v.ElementName, v.Name) for v in
self._conn.Msvm_ComputerSystem(['ElementName', 'Name'],
Caption="Virtual Machine")]
return vms
def get_cpu_metrics(self, vm_name):
vm = self._lookup_vm(vm_name)
cpu_sd = self._get_vm_resources(vm, self._PROC_SETTING)[0]
cpu_metrics_def = self._get_metric_def(self._CPU_METRIC_NAME)
cpu_metric_aggr = self._get_metrics(vm, cpu_metrics_def)
cpu_used = 0
if cpu_metric_aggr:
cpu_used = int(cpu_metric_aggr[0].MetricValue)
return (cpu_used,
int(cpu_sd.VirtualQuantity),
int(vm.OnTimeInMilliseconds))
def get_memory_metrics(self, vm_name):
vm = self._lookup_vm(vm_name)
memory_def = self._get_metric_def(self._MEMORY_METRIC_NAME)
metric_memory = self._get_metrics(vm, memory_def)
memory_usage = 0
if metric_memory:
memory_usage = int(metric_memory[0].MetricValue)
return memory_usage
def get_vnic_metrics(self, vm_name):
vm = self._lookup_vm(vm_name)
ports = self._get_vm_resources(vm, self._ETH_PORT_ALLOC)
vnics = self._get_vm_resources(vm, self._SYNTH_ETH_PORT)
metric_def_in = self._get_metric_def(self._NET_IN_METRIC_NAME)
metric_def_out = self._get_metric_def(self._NET_OUT_METRIC_NAME)
for port in ports:
vnic = [v for v in vnics if port.Parent == v.path_()][0]
metric_value_instances = self._get_metric_value_instances(
port.associators(wmi_result_class=self._PORT_ACL_SET_DATA),
self._BASE_METRICS_VALUE)
metric_values = self._sum_metric_values_by_defs(
metric_value_instances, [metric_def_in, metric_def_out])
yield {
'rx_mb': metric_values[0],
'tx_mb': metric_values[1],
'element_name': vnic.ElementName,
'address': vnic.Address
}
def get_disk_metrics(self, vm_name):
vm = self._lookup_vm(vm_name)
metric_def_r = self._get_metric_def(self._DISK_RD_METRIC_NAME)
metric_def_w = self._get_metric_def(self._DISK_WR_METRIC_NAME)
disks = self._get_vm_resources(vm, self._STORAGE_ALLOC)
for disk in disks:
metric_values = self._get_metric_values(
disk, [metric_def_r, metric_def_w])
# Thi sis e.g. the VHD file location
if disk.HostResource:
host_resource = disk.HostResource[0]
yield {
# Values are in megabytes
'read_mb': metric_values[0],
'write_mb': metric_values[1],
'instance_id': disk.InstanceID,
'host_resource': host_resource
}
def get_disk_latency_metrics(self, vm_name):
vm = self._lookup_vm(vm_name)
metric_latency_def = self._get_metric_def(
self._DISK_LATENCY_METRIC_NAME)
disks = self._get_vm_resources(vm, self._STORAGE_ALLOC)
for disk in disks:
metric_values = self._get_metric_values(
disk, [metric_latency_def])
yield {
'disk_latency': metric_values[0],
'instance_id': disk.InstanceID,
}
def get_disk_iops_count(self, vm_name):
vm = self._lookup_vm(vm_name)
metric_def_iops = self._get_metric_def(self._DISK_IOPS_METRIC_NAME)
disks = self._get_vm_resources(vm, self._STORAGE_ALLOC)
for disk in disks:
metric_values = self._get_metric_values(
disk, [metric_def_iops])
yield {
'iops_count': metric_values[0],
'instance_id': disk.InstanceID,
}
@staticmethod
def _sum_metric_values(metrics):
tot_metric_val = 0
for metric in metrics:
tot_metric_val += int(metric.MetricValue)
return tot_metric_val
def _sum_metric_values_by_defs(self, element_metrics, metric_defs):
metric_values = []
for metric_def in metric_defs:
if metric_def:
metrics = self._filter_metrics(element_metrics, metric_def)
metric_values.append(self._sum_metric_values(metrics))
else:
# In case the metric is not defined on this host
metric_values.append(0)
return metric_values
@staticmethod
def _get_metric_value_instances(elements, result_class):
instances = []
for el in elements:
associators = el.associators(wmi_result_class=result_class)
if associators:
instances.append(associators[0])
return instances
def _get_metric_values(self, element, metric_defs):
element_metrics = element.associators(
wmi_association_class=self._METRICS_ME)
return self._sum_metric_values_by_defs(element_metrics, metric_defs)
def _lookup_vm(self, vm_name):
vms = self._conn.Msvm_ComputerSystem(ElementName=vm_name)
n = len(vms)
if n == 0:
raise inspector.InstanceNotFoundException(
_('VM %s not found on Hyper-V') % vm_name)
elif n > 1:
raise HyperVException(_('Duplicate VM name found: %s') % vm_name)
else:
return vms[0]
def _get_metrics(self, element, metric_def):
return self._filter_metrics(
element.associators(
wmi_association_class=self._METRICS_ME), metric_def)
@staticmethod
def _filter_metrics(all_metrics, metric_def):
return [v for v in all_metrics if
v.MetricDefinitionId == metric_def.Id]
def _get_metric_def(self, metric_def):
metric = self._conn.CIM_BaseMetricDefinition(ElementName=metric_def)
if metric:
return metric[0]
def _get_vm_setting_data(self, vm):
vm_settings = vm.associators(
wmi_result_class=self._VS_SETTING_DATA)
# Avoid snapshots
return [s for s in vm_settings if
s.VirtualSystemType == self._VIRTUAL_SYSTEM_TYPE_REALIZED][0]
def _get_vm_resources(self, vm, resource_class):
setting_data = self._get_vm_setting_data(vm)
return setting_data.associators(wmi_result_class=resource_class)

View File

@ -15,37 +15,83 @@
Tests for Hyper-V inspector.
"""
import sys
import mock
from os_win import exceptions as os_win_exc
from oslo_utils import units
from oslotest import base
from ceilometer.compute.virt.hyperv import inspector as hyperv_inspector
from ceilometer.compute.virt import inspector as virt_inspector
class TestHyperVInspection(base.BaseTestCase):
def setUp(self):
@mock.patch.object(hyperv_inspector, 'utilsfactory', mock.MagicMock())
@mock.patch.object(hyperv_inspector.HyperVInspector,
'_compute_host_max_cpu_clock')
def setUp(self, mock_compute_host_cpu_clock):
self._inspector = hyperv_inspector.HyperVInspector()
self._inspector._utils = mock.MagicMock()
super(TestHyperVInspection, self).setUp()
def test_converted_exception(self):
self._inspector._utils.get_cpu_metrics.side_effect = (
os_win_exc.OSWinException)
self.assertRaises(virt_inspector.InspectorException,
self._inspector.inspect_cpus, mock.sentinel.instance)
self._inspector._utils.get_cpu_metrics.side_effect = (
os_win_exc.HyperVException)
self.assertRaises(virt_inspector.InspectorException,
self._inspector.inspect_cpus, mock.sentinel.instance)
self._inspector._utils.get_cpu_metrics.side_effect = (
os_win_exc.NotFound(resource='foofoo'))
self.assertRaises(virt_inspector.InstanceNotFoundException,
self._inspector.inspect_cpus, mock.sentinel.instance)
def test_assert_original_traceback_maintained(self):
def bar(self):
foo = "foofoo"
raise os_win_exc.NotFound(resource=foo)
self._inspector._utils.get_cpu_metrics.side_effect = bar
try:
self._inspector.inspect_cpus(mock.sentinel.instance)
self.fail("Test expected exception, but it was not raised.")
except virt_inspector.InstanceNotFoundException:
# exception has been raised as expected.
_, _, trace = sys.exc_info()
while trace.tb_next:
# iterate until the original exception source, bar.
trace = trace.tb_next
# original frame will contain the 'foo' variable.
self.assertEqual('foofoo', trace.tb_frame.f_locals['foo'])
@mock.patch.object(hyperv_inspector, 'utilsfactory')
def test_compute_host_max_cpu_clock(self, mock_utilsfactory):
mock_cpu = {'MaxClockSpeed': 1000}
hostutils = mock_utilsfactory.get_hostutils.return_value.get_cpus_info
hostutils.return_value = [mock_cpu, mock_cpu]
cpu_clock = self._inspector._compute_host_max_cpu_clock()
self.assertEqual(2000.0, cpu_clock)
def test_inspect_cpus(self):
fake_instance_name = 'fake_instance_name'
fake_host_cpu_clock = 1000
fake_host_cpu_count = 2
fake_cpu_clock_used = 2000
fake_cpu_count = 3000
fake_uptime = 4000
self._inspector._host_max_cpu_clock = 4000.0
fake_cpu_percent_used = (fake_cpu_clock_used /
float(fake_host_cpu_clock * fake_cpu_count))
self._inspector._host_max_cpu_clock)
fake_cpu_time = (int(fake_uptime * fake_cpu_percent_used) *
1000)
self._inspector._utils.get_host_cpu_info.return_value = (
fake_host_cpu_clock, fake_host_cpu_count)
self._inspector._utils.get_cpu_metrics.return_value = (
fake_cpu_clock_used, fake_cpu_count, fake_uptime)
@ -54,9 +100,7 @@ class TestHyperVInspection(base.BaseTestCase):
self.assertEqual(fake_cpu_count, cpu_stats.number)
self.assertEqual(fake_cpu_time, cpu_stats.time)
@mock.patch('ceilometer.compute.virt.hyperv.utilsv2.UtilsV2.'
'get_memory_metrics')
def test_inspect_memory_usage(self, mock_get_memory_metrics):
def test_inspect_memory_usage(self):
fake_usage = self._inspector._utils.get_memory_metrics.return_value
usage = self._inspector.inspect_memory_usage(
mock.sentinel.FAKE_INSTANCE, mock.sentinel.FAKE_DURATION)

View File

@ -1,283 +0,0 @@
# Copyright 2013 Cloudbase Solutions Srl
#
# 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.
"""
Tests for Hyper-V utilsv2.
"""
import mock
from oslotest import base
from ceilometer.compute.virt.hyperv import utilsv2 as utilsv2
from ceilometer.compute.virt import inspector
class TestUtilsV2(base.BaseTestCase):
_FAKE_RETURN_CLASS = 'fake_return_class'
def setUp(self):
self._utils = utilsv2.UtilsV2()
self._utils._conn = mock.MagicMock()
self._utils._conn_cimv2 = mock.MagicMock()
super(TestUtilsV2, self).setUp()
@mock.patch.object(utilsv2.UtilsV2, '_get_metrics')
@mock.patch.object(utilsv2.UtilsV2, '_get_metric_def')
@mock.patch.object(utilsv2.UtilsV2, '_lookup_vm')
def test_get_memory_metrics(self, mock_lookup_vm, mock_get_metric_def,
mock_get_metrics):
mock_vm = mock_lookup_vm.return_value
mock_metric_def = mock_get_metric_def.return_value
metric_memory = mock.MagicMock()
metric_memory.MetricValue = 3
mock_get_metrics.return_value = [metric_memory]
response = self._utils.get_memory_metrics(mock.sentinel._FAKE_INSTANCE)
mock_lookup_vm.assert_called_once_with(mock.sentinel._FAKE_INSTANCE)
mock_get_metric_def.assert_called_once_with(
self._utils._MEMORY_METRIC_NAME)
mock_get_metrics.assert_called_once_with(mock_vm, mock_metric_def)
self.assertEqual(3, response)
def test_get_host_cpu_info(self):
_fake_clock_speed = 1000
_fake_cpu_count = 2
mock_cpu = mock.MagicMock()
mock_cpu.MaxClockSpeed = _fake_clock_speed
self._utils._conn_cimv2.Win32_Processor.return_value = [mock_cpu,
mock_cpu]
cpu_info = self._utils.get_host_cpu_info()
self.assertEqual(_fake_clock_speed, cpu_info[0])
self.assertEqual(_fake_cpu_count, cpu_info[1])
def test_get_all_vms(self):
fake_vm_element_name = "fake_vm_element_name"
fake_vm_name = "fake_vm_name"
mock_vm = mock.MagicMock()
mock_vm.ElementName = fake_vm_element_name
mock_vm.Name = fake_vm_name
self._utils._conn.Msvm_ComputerSystem.return_value = [mock_vm]
vms = self._utils.get_all_vms()
self.assertEqual((fake_vm_element_name, fake_vm_name), vms[0])
def test_get_cpu_metrics(self):
fake_vm_element_name = "fake_vm_element_name"
fake_cpu_count = 2
fake_uptime = 1000
fake_cpu_metric_val = 2000
self._utils._lookup_vm = mock.MagicMock()
self._utils._lookup_vm().OnTimeInMilliseconds = fake_uptime
self._utils._get_vm_resources = mock.MagicMock()
mock_res = self._utils._get_vm_resources()[0]
mock_res.VirtualQuantity = fake_cpu_count
self._utils._get_metrics = mock.MagicMock()
self._utils._get_metrics()[0].MetricValue = fake_cpu_metric_val
cpu_metrics = self._utils.get_cpu_metrics(fake_vm_element_name)
self.assertEqual(3, len(cpu_metrics))
self.assertEqual(fake_cpu_metric_val, cpu_metrics[0])
self.assertEqual(fake_cpu_count, cpu_metrics[1])
self.assertEqual(fake_uptime, cpu_metrics[2])
@mock.patch('ceilometer.compute.virt.hyperv.utilsv2.UtilsV2'
'._sum_metric_values_by_defs')
@mock.patch('ceilometer.compute.virt.hyperv.utilsv2.UtilsV2'
'._get_metric_value_instances')
def test_get_vnic_metrics(self, mock_get_instances, mock_get_by_defs):
fake_vm_element_name = "fake_vm_element_name"
fake_vnic_element_name = "fake_vnic_name"
fake_vnic_address = "fake_vnic_address"
fake_vnic_path = "fake_vnic_path"
fake_rx_mb = 1000
fake_tx_mb = 2000
self._utils._lookup_vm = mock.MagicMock()
self._utils._get_vm_resources = mock.MagicMock()
mock_port = mock.MagicMock()
mock_port.Parent = fake_vnic_path
mock_vnic = mock.MagicMock()
mock_vnic.path_.return_value = fake_vnic_path
mock_vnic.ElementName = fake_vnic_element_name
mock_vnic.Address = fake_vnic_address
self._utils._get_vm_resources.side_effect = [[mock_port], [mock_vnic]]
self._utils._get_metric_def = mock.MagicMock()
mock_get_by_defs.return_value = [fake_rx_mb, fake_tx_mb]
vnic_metrics = list(self._utils.get_vnic_metrics(fake_vm_element_name))
self.assertEqual(1, len(vnic_metrics))
self.assertEqual(fake_rx_mb, vnic_metrics[0]['rx_mb'])
self.assertEqual(fake_tx_mb, vnic_metrics[0]['tx_mb'])
self.assertEqual(fake_vnic_element_name,
vnic_metrics[0]['element_name'])
self.assertEqual(fake_vnic_address, vnic_metrics[0]['address'])
def test_get_disk_metrics(self):
fake_vm_element_name = "fake_vm_element_name"
fake_host_resource = "fake_host_resource"
fake_instance_id = "fake_instance_id"
fake_read_mb = 1000
fake_write_mb = 2000
self._utils._lookup_vm = mock.MagicMock()
mock_disk = mock.MagicMock()
mock_disk.HostResource = [fake_host_resource]
mock_disk.InstanceID = fake_instance_id
self._utils._get_vm_resources = mock.MagicMock(
return_value=[mock_disk])
self._utils._get_metric_def = mock.MagicMock()
self._utils._get_metric_values = mock.MagicMock()
self._utils._get_metric_values.return_value = [fake_read_mb,
fake_write_mb]
disk_metrics = list(self._utils.get_disk_metrics(fake_vm_element_name))
self.assertEqual(1, len(disk_metrics))
self.assertEqual(fake_read_mb, disk_metrics[0]['read_mb'])
self.assertEqual(fake_write_mb, disk_metrics[0]['write_mb'])
self.assertEqual(fake_instance_id, disk_metrics[0]['instance_id'])
self.assertEqual(fake_host_resource, disk_metrics[0]['host_resource'])
def test_get_disk_latency(self):
fake_vm_name = mock.sentinel.VM_NAME
fake_instance_id = mock.sentinel.FAKE_INSTANCE_ID
fake_latency = mock.sentinel.FAKE_LATENCY
self._utils._lookup_vm = mock.MagicMock()
mock_disk = mock.MagicMock()
mock_disk.InstanceID = fake_instance_id
self._utils._get_vm_resources = mock.MagicMock(
return_value=[mock_disk])
self._utils._get_metric_values = mock.MagicMock(
return_value=[fake_latency])
disk_metrics = list(self._utils.get_disk_latency_metrics(fake_vm_name))
self.assertEqual(1, len(disk_metrics))
self.assertEqual(fake_latency, disk_metrics[0]['disk_latency'])
self.assertEqual(fake_instance_id, disk_metrics[0]['instance_id'])
def test_get_disk_iops_metrics(self):
fake_vm_name = mock.sentinel.VM_NAME
fake_instance_id = mock.sentinel.FAKE_INSTANCE_ID
fake_iops_count = mock.sentinel.FAKE_IOPS_COUNT
self._utils._lookup_vm = mock.MagicMock()
mock_disk = mock.MagicMock()
mock_disk.InstanceID = fake_instance_id
self._utils._get_vm_resources = mock.MagicMock(
return_value=[mock_disk])
self._utils._get_metric_values = mock.MagicMock(
return_value=[fake_iops_count])
disk_metrics = list(self._utils.get_disk_iops_count(fake_vm_name))
self.assertEqual(1, len(disk_metrics))
self.assertEqual(fake_iops_count, disk_metrics[0]['iops_count'])
self.assertEqual(fake_instance_id, disk_metrics[0]['instance_id'])
def test_get_metric_value_instances(self):
mock_el1 = mock.MagicMock()
mock_associator = mock.MagicMock()
mock_el1.associators.return_value = [mock_associator]
mock_el2 = mock.MagicMock()
mock_el2.associators.return_value = []
returned = self._utils._get_metric_value_instances(
[mock_el1, mock_el2], self._FAKE_RETURN_CLASS)
self.assertEqual([mock_associator], returned)
def test_lookup_vm(self):
fake_vm_element_name = "fake_vm_element_name"
fake_vm = "fake_vm"
self._utils._conn.Msvm_ComputerSystem.return_value = [fake_vm]
vm = self._utils._lookup_vm(fake_vm_element_name)
self.assertEqual(fake_vm, vm)
def test_lookup_vm_not_found(self):
fake_vm_element_name = "fake_vm_element_name"
self._utils._conn.Msvm_ComputerSystem.return_value = []
self.assertRaises(inspector.InstanceNotFoundException,
self._utils._lookup_vm, fake_vm_element_name)
def test_lookup_vm_duplicate_found(self):
fake_vm_element_name = "fake_vm_element_name"
fake_vm = "fake_vm"
self._utils._conn.Msvm_ComputerSystem.return_value = [fake_vm, fake_vm]
self.assertRaises(utilsv2.HyperVException,
self._utils._lookup_vm, fake_vm_element_name)
def test_get_metric_values(self):
fake_metric_def_id = "fake_metric_def_id"
fake_metric_value = "1000"
mock_metric = mock.MagicMock()
mock_metric.MetricDefinitionId = fake_metric_def_id
mock_metric.MetricValue = fake_metric_value
mock_element = mock.MagicMock()
mock_element.associators.return_value = [mock_metric]
mock_metric_def = mock.MagicMock()
mock_metric_def.Id = fake_metric_def_id
metric_values = self._utils._get_metric_values(mock_element,
[mock_metric_def])
self.assertEqual(1, len(metric_values))
self.assertEqual(int(fake_metric_value), metric_values[0])
def test_get_vm_setting_data(self):
mock_vm_s = mock.MagicMock()
mock_vm_s.VirtualSystemType = self._utils._VIRTUAL_SYSTEM_TYPE_REALIZED
mock_vm = mock.MagicMock()
mock_vm.associators.return_value = [mock_vm_s]
vm_setting_data = self._utils._get_vm_setting_data(mock_vm)
self.assertEqual(mock_vm_s, vm_setting_data)

View File

@ -13,6 +13,7 @@ happybase!=0.7,>=0.5;python_version=='2.7' # MIT
httplib2>=0.7.5 # MIT
mock>=1.2 # BSD
PyMySQL>=0.6.2 # MIT License
os-win>=0.2.1 # Apache-2.0
oslo.cache>=0.8.0 # Apache-2.0
# Docs Requirements
oslosphinx!=3.4.0,>=2.5.0 # Apache-2.0