Adds Hyper-V compute inspector
Blueprint: hyper-v-agent Adds a compute inspector for Hyper-V. Supports Windows Server / Hyper-V Server 2012 and above. Disk stats are supported starting with Hyper-V 2012 R2. Change-Id: Ib6499b631a2f7e406198b13f4b5788a3b880fb1b
This commit is contained in:
parent
90ad86c084
commit
81e336a376
0
ceilometer/compute/virt/hyperv/__init__.py
Normal file
0
ceilometer/compute/virt/hyperv/__init__.py
Normal file
87
ceilometer/compute/virt/hyperv/inspector.py
Normal file
87
ceilometer/compute/virt/hyperv/inspector.py
Normal file
@ -0,0 +1,87 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2013 Cloudbase Solutions Srl
|
||||
#
|
||||
# Author: Claudiu Belu <cbelu@cloudbasesolutions.com>
|
||||
# Alessandro Pilotti <apilotti@cloudbasesolutions.com>
|
||||
#
|
||||
# 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.
|
||||
"""Implementation of Inspector abstraction for Hyper-V"""
|
||||
|
||||
from oslo.config import cfg
|
||||
|
||||
from ceilometer.compute.virt import inspector as virt_inspector
|
||||
from ceilometer.compute.virt.hyperv import utilsv2
|
||||
from ceilometer.openstack.common import log
|
||||
|
||||
CONF = cfg.CONF
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
|
||||
class HyperVInspector(virt_inspector.Inspector):
|
||||
|
||||
def __init__(self):
|
||||
super(HyperVInspector, self).__init__()
|
||||
self._utils = utilsv2.UtilsV2()
|
||||
|
||||
def inspect_instances(self):
|
||||
for element_name, name in self._utils.get_all_vms():
|
||||
yield virt_inspector.Instance(
|
||||
name=element_name,
|
||||
UUID=name)
|
||||
|
||||
def inspect_cpus(self, instance_name):
|
||||
(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))
|
||||
# Nanoseconds
|
||||
cpu_time = (long(uptime * cpu_percent_used) *
|
||||
1000)
|
||||
|
||||
return virt_inspector.CPUStats(number=cpu_count, time=cpu_time)
|
||||
|
||||
def inspect_vnics(self, instance_name):
|
||||
for vnic_metrics in self._utils.get_vnic_metrics(instance_name):
|
||||
interface = virt_inspector.Interface(
|
||||
name=vnic_metrics["element_name"],
|
||||
mac=vnic_metrics["address"],
|
||||
fref=None,
|
||||
parameters=None)
|
||||
|
||||
stats = virt_inspector.InterfaceStats(
|
||||
rx_bytes=vnic_metrics['rx_bytes'],
|
||||
rx_packets=0,
|
||||
tx_bytes=vnic_metrics['tx_bytes'],
|
||||
tx_packets=0)
|
||||
|
||||
yield (interface, stats)
|
||||
|
||||
def inspect_disks(self, instance_name):
|
||||
for disk_metrics in self._utils.get_disk_metrics(instance_name):
|
||||
device = dict([(i, disk_metrics[i])
|
||||
for i in ['instance_id', 'host_resource']
|
||||
if i in disk_metrics])
|
||||
|
||||
disk = virt_inspector.Disk(device=device)
|
||||
stats = virt_inspector.DiskStats(
|
||||
read_requests=0,
|
||||
# Return bytes
|
||||
read_bytes=disk_metrics['read_mb'] * 1024,
|
||||
write_requests=0,
|
||||
write_bytes=disk_metrics['write_mb'] * 1024,
|
||||
errors=0)
|
||||
|
||||
yield (disk, stats)
|
193
ceilometer/compute/virt/hyperv/utilsv2.py
Normal file
193
ceilometer/compute/virt/hyperv/utilsv2.py
Normal file
@ -0,0 +1,193 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2013 Cloudbase Solutions Srl
|
||||
#
|
||||
# Author: Claudiu Belu <cbelu@cloudbasesolutions.com>
|
||||
# Alessandro Pilotti <apilotti@cloudbasesolutions.com>
|
||||
#
|
||||
# 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 oslo.config import cfg
|
||||
|
||||
from ceilometer.compute.virt import inspector
|
||||
from ceilometer.openstack.common.gettextutils import _
|
||||
from ceilometer.openstack.common import log as logging
|
||||
|
||||
CONF = cfg.CONF
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class HyperVException(inspector.InspectorException):
|
||||
pass
|
||||
|
||||
|
||||
class UtilsV2(object):
|
||||
|
||||
_VIRTUAL_SYSTEM_TYPE_REALIZED = 'Microsoft:Hyper-V:System:Realized'
|
||||
|
||||
_PROC_SETTING = 'Msvm_ProcessorSettingData'
|
||||
_SYNTH_ETH_PORT = 'Msvm_SyntheticEthernetPortSettingData'
|
||||
_ETH_PORT_ALLOC = 'Msvm_EthernetPortAllocationSettingData'
|
||||
_STORAGE_ALLOC = 'Msvm_StorageAllocationSettingData'
|
||||
_VS_SETTING_DATA = 'Msvm_VirtualSystemSettingData'
|
||||
_AGGREG_METRIC = 'Msvm_AggregationMetricDefinition'
|
||||
_METRICS_ME = 'Msvm_MetricForME'
|
||||
|
||||
_CPU_METRIC_NAME = 'Aggregated Average CPU Utilization'
|
||||
_NET_IN_METRIC_NAME = 'Aggregated Filtered Incoming Network Traffic'
|
||||
_NET_OUT_METRIC_NAME = 'Aggregated Filtered Outgoing Network Traffic'
|
||||
# Disk metrics are supported from Hyper-V 2012 R2
|
||||
_DISK_RD_METRIC_NAME = 'Aggregated Disk Data Read'
|
||||
_DISK_WR_METRIC_NAME = 'Aggregated Disk Data Written'
|
||||
|
||||
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)[0]
|
||||
|
||||
return (int(cpu_metric_aggr.MetricValue),
|
||||
cpu_sd.VirtualQuantity,
|
||||
long(vm.OnTimeInMilliseconds))
|
||||
|
||||
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_values = self._get_metric_values(
|
||||
port, [metric_def_in, metric_def_out])
|
||||
|
||||
yield {
|
||||
'rx_bytes': metric_values[0],
|
||||
'tx_bytes': 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 _sum_metric_values(self, metrics):
|
||||
tot_metric_val = 0
|
||||
for metric in metrics:
|
||||
tot_metric_val += long(metric.MetricValue)
|
||||
return tot_metric_val
|
||||
|
||||
def _get_metric_values(self, element, metric_defs):
|
||||
element_metrics = element.associators(
|
||||
wmi_association_class=self._METRICS_ME)
|
||||
|
||||
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
|
||||
|
||||
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)
|
||||
|
||||
def _filter_metrics(self, 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)
|
@ -83,6 +83,7 @@ ceilometer.storage =
|
||||
|
||||
ceilometer.compute.virt =
|
||||
libvirt = ceilometer.compute.virt.libvirt.inspector:LibvirtInspector
|
||||
hyperv = ceilometer.compute.virt.hyperv.inspector:HyperVInspector
|
||||
|
||||
ceilometer.transformer =
|
||||
accumulator = ceilometer.transformer.accumulator:TransformerAccumulator
|
||||
|
0
tests/compute/virt/hyperv/__init__.py
Normal file
0
tests/compute/virt/hyperv/__init__.py
Normal file
126
tests/compute/virt/hyperv/test_inspector.py
Normal file
126
tests/compute/virt/hyperv/test_inspector.py
Normal file
@ -0,0 +1,126 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2013 Cloudbase Solutions Srl
|
||||
#
|
||||
# Author: Alessandro Pilotti <apilotti@cloudbasesolutions.com>
|
||||
#
|
||||
# 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 inspector.
|
||||
"""
|
||||
|
||||
import mock
|
||||
|
||||
from ceilometer.compute.virt.hyperv import inspector as hyperv_inspector
|
||||
from ceilometer.tests import base as test_base
|
||||
|
||||
|
||||
class TestHyperVInspection(test_base.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self._inspector = hyperv_inspector.HyperVInspector()
|
||||
self._inspector._utils = mock.MagicMock()
|
||||
|
||||
super(TestHyperVInspection, self).setUp()
|
||||
|
||||
def test_inspect_instances(self):
|
||||
fake_name = 'fake_name'
|
||||
fake_uuid = 'fake_uuid'
|
||||
fake_instances = [(fake_name, fake_uuid)]
|
||||
self._inspector._utils.get_all_vms.return_value = fake_instances
|
||||
|
||||
inspected_instances = list(self._inspector.inspect_instances())
|
||||
|
||||
self.assertEqual(1, len(inspected_instances))
|
||||
self.assertEqual(fake_name, inspected_instances[0].name)
|
||||
self.assertEqual(fake_uuid, inspected_instances[0].UUID)
|
||||
|
||||
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
|
||||
|
||||
fake_cpu_percent_used = (fake_cpu_clock_used /
|
||||
float(fake_host_cpu_clock * fake_cpu_count))
|
||||
fake_cpu_time = (long(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)
|
||||
|
||||
cpu_stats = self._inspector.inspect_cpus(fake_instance_name)
|
||||
|
||||
self.assertEqual(fake_cpu_count, cpu_stats.number)
|
||||
self.assertEqual(fake_cpu_time, cpu_stats.time)
|
||||
|
||||
def test_inspect_vnics(self):
|
||||
fake_instance_name = 'fake_instance_name'
|
||||
fake_rx_bytes = 1000
|
||||
fake_tx_bytes = 2000
|
||||
fake_element_name = 'fake_element_name'
|
||||
fake_address = 'fake_address'
|
||||
|
||||
self._inspector._utils.get_vnic_metrics.return_value = [{
|
||||
'rx_bytes': fake_rx_bytes,
|
||||
'tx_bytes': fake_tx_bytes,
|
||||
'element_name': fake_element_name,
|
||||
'address': fake_address}]
|
||||
|
||||
inspected_vnics = list(self._inspector.inspect_vnics(
|
||||
fake_instance_name))
|
||||
|
||||
self.assertEqual(1, len(inspected_vnics))
|
||||
self.assertEqual(2, len(inspected_vnics[0]))
|
||||
|
||||
inspected_vnic, inspected_stats = inspected_vnics[0]
|
||||
|
||||
self.assertEqual(fake_element_name, inspected_vnic.name)
|
||||
self.assertEqual(fake_address, inspected_vnic.mac)
|
||||
|
||||
self.assertEqual(fake_rx_bytes, inspected_stats.rx_bytes)
|
||||
self.assertEqual(fake_tx_bytes, inspected_stats.tx_bytes)
|
||||
|
||||
def test_inspect_disks(self):
|
||||
fake_instance_name = 'fake_instance_name'
|
||||
fake_read_mb = 1000
|
||||
fake_write_mb = 2000
|
||||
fake_instance_id = "fake_fake_instance_id"
|
||||
fake_host_resource = "fake_host_resource"
|
||||
|
||||
fake_device = {"instance_id": fake_instance_id,
|
||||
"host_resource": fake_host_resource}
|
||||
|
||||
self._inspector._utils.get_disk_metrics.return_value = [{
|
||||
'read_mb': fake_read_mb,
|
||||
'write_mb': fake_write_mb,
|
||||
'instance_id': fake_instance_id,
|
||||
'host_resource': fake_host_resource}]
|
||||
|
||||
inspected_disks = list(self._inspector.inspect_disks(
|
||||
fake_instance_name))
|
||||
|
||||
self.assertEqual(1, len(inspected_disks))
|
||||
self.assertEqual(2, len(inspected_disks[0]))
|
||||
|
||||
inspected_disk, inspected_stats = inspected_disks[0]
|
||||
|
||||
self.assertEqual(fake_device, inspected_disk.device)
|
||||
|
||||
self.assertEqual(fake_read_mb * 1024, inspected_stats.read_bytes)
|
||||
self.assertEqual(fake_write_mb * 1024, inspected_stats.write_bytes)
|
206
tests/compute/virt/hyperv/test_utilsv2.py
Normal file
206
tests/compute/virt/hyperv/test_utilsv2.py
Normal file
@ -0,0 +1,206 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2013 Cloudbase Solutions Srl
|
||||
#
|
||||
# Author: Alessandro Pilotti <apilotti@cloudbasesolutions.com>
|
||||
#
|
||||
# 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 ceilometer.compute.virt import inspector
|
||||
from ceilometer.compute.virt.hyperv import utilsv2 as utilsv2
|
||||
from ceilometer.tests import base as test_base
|
||||
|
||||
|
||||
class TestUtilsV2(test_base.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self._utils = utilsv2.UtilsV2()
|
||||
self._utils._conn = mock.MagicMock()
|
||||
self._utils._conn_cimv2 = mock.MagicMock()
|
||||
|
||||
super(TestUtilsV2, self).setUp()
|
||||
|
||||
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])
|
||||
|
||||
def test_get_vnic_metrics(self):
|
||||
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_bytes = 1000
|
||||
fake_tx_bytes = 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()
|
||||
|
||||
self._utils._get_metric_values = mock.MagicMock()
|
||||
self._utils._get_metric_values.return_value = [fake_rx_bytes,
|
||||
fake_tx_bytes]
|
||||
|
||||
vnic_metrics = list(self._utils.get_vnic_metrics(fake_vm_element_name))
|
||||
|
||||
self.assertEqual(1, len(vnic_metrics))
|
||||
self.assertEqual(fake_rx_bytes, vnic_metrics[0]['rx_bytes'])
|
||||
self.assertEqual(fake_tx_bytes, vnic_metrics[0]['tx_bytes'])
|
||||
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_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(long(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)
|
Loading…
Reference in New Issue
Block a user