diff --git a/ceilometer/compute/virt/hyperv/inspector.py b/ceilometer/compute/virt/hyperv/inspector.py index 4f1f7606..38409295 100644 --- a/ceilometer/compute/virt/hyperv/inspector.py +++ b/ceilometer/compute/virt/hyperv/inspector.py @@ -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) diff --git a/ceilometer/compute/virt/hyperv/utilsv2.py b/ceilometer/compute/virt/hyperv/utilsv2.py deleted file mode 100644 index d6d7e30e..00000000 --- a/ceilometer/compute/virt/hyperv/utilsv2.py +++ /dev/null @@ -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) diff --git a/ceilometer/tests/unit/compute/virt/hyperv/test_inspector.py b/ceilometer/tests/unit/compute/virt/hyperv/test_inspector.py index 76516a4e..7df4f2e4 100644 --- a/ceilometer/tests/unit/compute/virt/hyperv/test_inspector.py +++ b/ceilometer/tests/unit/compute/virt/hyperv/test_inspector.py @@ -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) diff --git a/ceilometer/tests/unit/compute/virt/hyperv/test_utilsv2.py b/ceilometer/tests/unit/compute/virt/hyperv/test_utilsv2.py deleted file mode 100644 index 5592ee3c..00000000 --- a/ceilometer/tests/unit/compute/virt/hyperv/test_utilsv2.py +++ /dev/null @@ -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) diff --git a/test-requirements.txt b/test-requirements.txt index 964c21dd..297a6c90 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -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