def test_get_samples(self): next_value = iter(( virt_inspector.CPUUtilStats(util=40), virt_inspector.CPUUtilStats(util=60), )) def inspect_cpu_util(name, duration): return next(next_value) self.inspector.inspect_cpu_util = (mock. Mock(side_effect=inspect_cpu_util)) mgr = manager.AgentManager() pollster = cpu.CPUUtilPollster() def _verify_cpu_util_metering(expected_util): cache = {} samples = list(pollster.get_samples(mgr, cache, [self.instance])) self.assertEqual(1, len(samples)) self.assertEqual(set(['cpu_util']), set([s.name for s in samples])) self.assertEqual(expected_util, samples[0].volume) _verify_cpu_util_metering(40) _verify_cpu_util_metering(60)
def test_inspect_cpu_util(self): fake_instance = {'OS-EXT-SRV-ATTR:instance_name': 'fake_instance_name', 'id': 'fake_instance_id'} fake_stat = virt_inspector.CPUUtilStats(util=40) def fake_xenapi_request(method, args): metrics_rec = { 'memory_actual': '536870912', 'VCPUs_number': '1', 'VCPUs_utilisation': {'0': 0.4, } } if method == 'VM.get_by_name_label': return ['vm_ref'] elif method == 'VM.get_metrics': return 'metrics_ref' elif method == 'VM_metrics.get_record': return metrics_rec else: return None session = self.inspector.session with mock.patch.object(session, 'xenapi_request', side_effect=fake_xenapi_request): cpu_util_stat = self.inspector.inspect_cpu_util(fake_instance) self.assertEqual(fake_stat, cpu_util_stat)
def inspect_cpu_util(self, instance, duration=None): instance_name = util.instance_name(instance) vm_ref = self._lookup_by_name(instance_name) vcpus_number = int(self._call_xenapi("VM.get_VCPUs_max", vm_ref)) if vcpus_number <= 0: msg = _("Could not get VM %s CPU number") % instance_name raise XenapiException(msg) utils = 0.0 for index in range(vcpus_number): utils += float( self._call_xenapi("VM.query_data_source", vm_ref, "cpu%d" % index)) utils = utils / int(vcpus_number) * 100 return virt_inspector.CPUUtilStats(util=utils)
def inspect_cpu_util(self, instance, duration=None): vm_mobj = self._get_vm_mobj_not_power_off_or_raise(instance) cpu_util_counter_id = self._ops.get_perf_counter_id( VC_AVERAGE_CPU_CONSUMED_CNTR) cpu_util = self._ops.query_vm_aggregate_stats(vm_mobj, cpu_util_counter_id, duration) # For this counter vSphere returns values scaled-up by 100, since the # corresponding API can't return decimals, but only longs. # For e.g. if the utilization is 12.34%, the value returned is 1234. # Hence, dividing by 100. cpu_util = cpu_util / 100 return virt_inspector.CPUUtilStats(util=cpu_util)
def inspect_cpu_util(self, instance, duration=None): instance_name = util.instance_name(instance) vm_ref = self._lookup_by_name(instance_name) metrics_ref = self._call_xenapi("VM.get_metrics", vm_ref) metrics_rec = self._call_xenapi("VM_metrics.get_record", metrics_ref) vcpus_number = metrics_rec['VCPUs_number'] vcpus_utils = metrics_rec['VCPUs_utilisation'] if len(vcpus_utils) == 0: msg = _("Could not get VM %s CPU Utilization") % instance_name raise XenapiException(msg) utils = 0.0 for num in range(int(vcpus_number)): utils += vcpus_utils.get(str(num)) utils = utils / int(vcpus_number) * 100 return virt_inspector.CPUUtilStats(util=utils)
def inspect_cpu_util(self, instance, duration=None): vm_moid = self._ops.get_vm_moid(instance.id) if vm_moid is None: raise virt_inspector.InstanceNotFoundException( _('VM %s not found in VMware Vsphere') % instance.id) cpu_util_counter_id = self._ops.get_perf_counter_id( VC_AVERAGE_CPU_CONSUMED_CNTR) cpu_util = self._ops.query_vm_aggregate_stats( vm_moid, cpu_util_counter_id, duration) # For this counter vSphere returns values scaled-up by 100, since the # corresponding API can't return decimals, but only longs. # For e.g. if the utilization is 12.34%, the value returned is 1234. # Hence, dividing by 100. cpu_util = cpu_util / 100 return virt_inspector.CPUUtilStats(util=cpu_util)
def test_inspect_cpu_util(self): test_vm_mobj = mock.MagicMock() test_vm_mobj.value = "vm-21" fake_perf_counter_id = 'fake_perf_counter_id' fake_cpu_util_value = 60 fake_stat = virt_inspector.CPUUtilStats(util=60) self._inspector._get_vm_mobj_not_power_off_or_raise = mock.MagicMock() self._inspector._get_vm_mobj_not_power_off_or_raise.return_value = ( test_vm_mobj) ops_mock = self._inspector._ops ops_mock.get_perf_counter_id.return_value = fake_perf_counter_id (ops_mock.query_vm_aggregate_stats.return_value ) = fake_cpu_util_value * 100 cpu_util_stat = self._inspector.inspect_cpu_util(mock.MagicMock()) self.assertEqual(fake_stat, cpu_util_stat)
def test_inspect_cpu_util(self): fake_instance_moid = 'fake_instance_moid' fake_instance_id = 'fake_instance_id' fake_perf_counter_id = 'fake_perf_counter_id' fake_cpu_util_value = 60 fake_stat = virt_inspector.CPUUtilStats(util=60) def construct_mock_instance_object(fake_instance_id): instance_object = mock.MagicMock() instance_object.id = fake_instance_id return instance_object fake_instance = construct_mock_instance_object(fake_instance_id) self._inspector._ops.get_vm_moid.return_value = fake_instance_moid (self._inspector._ops.get_perf_counter_id. return_value) = fake_perf_counter_id (self._inspector._ops.query_vm_aggregate_stats. return_value) = fake_cpu_util_value * 100 cpu_util_stat = self._inspector.inspect_cpu_util(fake_instance) self.assertEqual(fake_stat, cpu_util_stat)
def test_inspect_cpu_util(self): fake_instance = { 'OS-EXT-SRV-ATTR:instance_name': 'fake_instance_name', 'id': 'fake_instance_id' } fake_stat = virt_inspector.CPUUtilStats(util=40) def fake_xenapi_request(method, args): if method == 'VM.get_by_name_label': return ['vm_ref'] elif method == 'VM.get_VCPUs_max': return '1' elif method == 'VM.query_data_source': return 0.4 else: return None session = self.inspector.session with mock.patch.object(session, 'xenapi_request', side_effect=fake_xenapi_request): cpu_util_stat = self.inspector.inspect_cpu_util(fake_instance) self.assertEqual(fake_stat, cpu_util_stat)
def inspect_cpu_util(self, instance, duration=None): """Inspect the CPU Utilization (%) for an instance. :param instance: the target instance :param duration: the last 'n' seconds, over which the value should be inspected. The PowerVM implementation does not make use of the duration field. :return: the percentage of CPU utilization """ # The duration is ignored. There is precedent for this in other # inspectors if the platform doesn't support duration. # # Given the nature of PowerVM to collect samples over coarse periods # of time, it does not lend well to duration based collection. # Therefore this works by gathering the latest utilization from the # samples and ignores the duration. # Get the current and previous sample. Delta is performed between # these two. uuid = self._puuid(instance) cur_date, cur_metric = self.vm_metrics.get_latest_metric(uuid) prev_date, prev_metric = self.vm_metrics.get_previous_metric(uuid) # If the current is none, then the instance can not be found in the # sample and an error should be raised. if cur_metric is None: raise virt_inspector.InstanceNotFoundException( _('VM %s not found in PowerVM Metrics Sample.') % instance.name) # Get the current data. cur_util_cap = cur_metric.processor.util_cap_proc_cycles cur_util_uncap = cur_metric.processor.util_uncap_proc_cycles cur_idle = cur_metric.processor.idle_proc_cycles cur_donated = cur_metric.processor.donated_proc_cycles cur_entitled = cur_metric.processor.entitled_proc_cycles # Get the previous sample data if prev_metric is None: # If there is no previous sample, that is either a new VM or is # a live migrated system. A live migrated system will pull all # of its metrics with it. The issue with this is it could have # CPU cycles for months of run time. So we can't really determine # the CPU utilization within the last X seconds...because to THIS # host its new (only in the cur_metric). So we error out, the # inspector will use a debug message in the log. LOG.warning( _LW("Unable to derive CPU Utilization for VM %s. " "It is either a new VM or was recently migrated. " "It will be collected in the next inspection " "cycle."), instance.name) message = (_("Unable to derive CPU Utilization for VM %s.") % instance.name) raise virt_inspector.InstanceNotFoundException(message) # Gather the previous metrics prev_util_cap = prev_metric.processor.util_cap_proc_cycles prev_util_uncap = prev_metric.processor.util_uncap_proc_cycles prev_idle = prev_metric.processor.idle_proc_cycles prev_donated = prev_metric.processor.donated_proc_cycles prev_entitled = prev_metric.processor.entitled_proc_cycles # Utilization can be driven by multiple factors on PowerVM. # PowerVM has 'entitled' cycles. These are cycles that, if the VM # needs them, they get them no matter what. # # In terms of how those cycles are returned from the API: # util_cap_proc_cycles - How many cycles from the guaranteed # capacity were used. # util_uncap_proc_cycles - How many cycles were used that were # taken from spare (which is either unused processors cycles # or donated cycles from other VMs). # idle_proc_cycles - How many cycles (as reported by the OS to the # hypervisor) were reported as idle. # donated_proc_cycles - Cycles that were not needed by this VM that # were given to another VM in need of cycles. # # # So the final utilization equation is: # (util cap + util uncap - idle - donated) / entitled # # It is important to note that idle and donated proc cycles are # included in the 'util_cap_proc_cycles'. That is why they are # subtracted out. # # The interesting aspect of this is that the CPU Utilization can go # dramatically above 100% if there are free processors or if the # other workloads are in a lull. util_cap = cur_util_cap - prev_util_cap util_uncap = cur_util_uncap - prev_util_uncap idle = cur_idle - prev_idle donated = cur_donated - prev_donated entitled = cur_entitled - prev_entitled # If the entitled is zero, that generally means that the VM has not # been started yet (everything else would be zero as well). So to # avoid a divide by zero error, just return 0% in that case. if entitled == 0: return virt_inspector.CPUUtilStats(util=0.0) util = float(util_cap + util_uncap - idle - donated) / float(entitled) # Utilization is reported as percents. Therefore, multiply by 100.0 # to get a readable percentage based format. return virt_inspector.CPUUtilStats(util=util * 100.0)