Modify metric-related filters for RequestSpec

Change-Id: I81762f3bbb022e3d3b85c17eaaf6392639753e08
Partially-Implements: blueprint request-spec-object-mitaka
This commit is contained in:
Sylvain Bauza 2015-07-16 18:05:33 +02:00
parent e792d50efa
commit 7358b68d07
13 changed files with 106 additions and 127 deletions

View File

@ -26,24 +26,19 @@ LOG = logging.getLogger(__name__)
class BaseCoreFilter(filters.BaseHostFilter):
def _get_cpu_allocation_ratio(self, host_state, filter_properties):
def _get_cpu_allocation_ratio(self, host_state, spec_obj):
raise NotImplementedError
@filters.compat_legacy_props
def host_passes(self, host_state, filter_properties):
def host_passes(self, host_state, spec_obj):
"""Return True if host has sufficient CPU cores."""
instance_type = filter_properties.get('instance_type')
if not instance_type:
return True
if not host_state.vcpus_total:
# Fail safe
LOG.warning(_LW("VCPUs not set; assuming CPU collection broken"))
return True
instance_vcpus = instance_type['vcpus']
instance_vcpus = spec_obj.vcpus
cpu_allocation_ratio = self._get_cpu_allocation_ratio(host_state,
filter_properties)
spec_obj)
vcpus_total = host_state.vcpus_total * cpu_allocation_ratio
# Only provide a VCPU limit to compute if the virt driver is reporting
@ -77,7 +72,7 @@ class BaseCoreFilter(filters.BaseHostFilter):
class CoreFilter(BaseCoreFilter):
"""CoreFilter filters based on CPU core utilization."""
def _get_cpu_allocation_ratio(self, host_state, filter_properties):
def _get_cpu_allocation_ratio(self, host_state, spec_obj):
return host_state.cpu_allocation_ratio
@ -87,7 +82,7 @@ class AggregateCoreFilter(BaseCoreFilter):
Fall back to global cpu_allocation_ratio if no per-aggregate setting found.
"""
def _get_cpu_allocation_ratio(self, host_state, filter_properties):
def _get_cpu_allocation_ratio(self, host_state, spec_obj):
aggregate_vals = utils.aggregate_values_from_key(
host_state,
'cpu_allocation_ratio')

View File

@ -32,22 +32,20 @@ CONF.register_opt(disk_allocation_ratio_opt)
class DiskFilter(filters.BaseHostFilter):
"""Disk Filter with over subscription flag."""
def _get_disk_allocation_ratio(self, host_state, filter_properties):
def _get_disk_allocation_ratio(self, host_state, spec_obj):
return CONF.disk_allocation_ratio
@filters.compat_legacy_props
def host_passes(self, host_state, filter_properties):
def host_passes(self, host_state, spec_obj):
"""Filter based on disk usage."""
instance_type = filter_properties.get('instance_type')
requested_disk = (1024 * (instance_type['root_gb'] +
instance_type['ephemeral_gb']) +
instance_type['swap'])
requested_disk = (1024 * (spec_obj.root_gb +
spec_obj.ephemeral_gb) +
spec_obj.swap)
free_disk_mb = host_state.free_disk_mb
total_usable_disk_mb = host_state.total_usable_disk_gb * 1024
disk_allocation_ratio = self._get_disk_allocation_ratio(
host_state, filter_properties)
host_state, spec_obj)
disk_mb_limit = total_usable_disk_mb * disk_allocation_ratio
used_disk_mb = total_usable_disk_mb - free_disk_mb
@ -73,7 +71,7 @@ class AggregateDiskFilter(DiskFilter):
found.
"""
def _get_disk_allocation_ratio(self, host_state, filter_properties):
def _get_disk_allocation_ratio(self, host_state, spec_obj):
aggregate_vals = utils.aggregate_values_from_key(
host_state,
'disk_allocation_ratio')

View File

@ -25,19 +25,14 @@ LOG = logging.getLogger(__name__)
class ExactCoreFilter(filters.BaseHostFilter):
"""Exact Core Filter."""
@filters.compat_legacy_props
def host_passes(self, host_state, filter_properties):
def host_passes(self, host_state, spec_obj):
"""Return True if host has the exact number of CPU cores."""
instance_type = filter_properties.get('instance_type')
if not instance_type:
return True
if not host_state.vcpus_total:
# Fail safe
LOG.warning(_LW("VCPUs not set; assuming CPU collection broken"))
return False
required_vcpus = instance_type['vcpus']
required_vcpus = spec_obj.vcpus
usable_vcpus = host_state.vcpus_total - host_state.vcpus_used
if required_vcpus != usable_vcpus:

View File

@ -23,13 +23,11 @@ LOG = logging.getLogger(__name__)
class ExactDiskFilter(filters.BaseHostFilter):
"""Exact Disk Filter."""
@filters.compat_legacy_props
def host_passes(self, host_state, filter_properties):
def host_passes(self, host_state, spec_obj):
"""Return True if host has the exact amount of disk available."""
instance_type = filter_properties.get('instance_type')
requested_disk = (1024 * (instance_type['root_gb'] +
instance_type['ephemeral_gb']) +
instance_type['swap'])
requested_disk = (1024 * (spec_obj.root_gb +
spec_obj.ephemeral_gb) +
spec_obj.swap)
if requested_disk != host_state.free_disk_mb:
LOG.debug("%(host_state)s does not have exactly "

View File

@ -23,11 +23,9 @@ LOG = logging.getLogger(__name__)
class ExactRamFilter(filters.BaseHostFilter):
"""Exact RAM Filter."""
@filters.compat_legacy_props
def host_passes(self, host_state, filter_properties):
def host_passes(self, host_state, spec_obj):
"""Return True if host has the exact amount of RAM available."""
instance_type = filter_properties.get('instance_type')
requested_ram = instance_type['memory_mb']
requested_ram = spec_obj.memory_mb
if requested_ram != host_state.free_ram_mb:
LOG.debug("%(host_state)s does not have exactly "
"%(requested_ram)s MB usable RAM, it has "

View File

@ -36,17 +36,16 @@ CONF.register_opt(max_io_ops_per_host_opt)
class IoOpsFilter(filters.BaseHostFilter):
"""Filter out hosts with too many concurrent I/O operations."""
def _get_max_io_ops_per_host(self, host_state, filter_properties):
def _get_max_io_ops_per_host(self, host_state, spec_obj):
return CONF.max_io_ops_per_host
@filters.compat_legacy_props
def host_passes(self, host_state, filter_properties):
def host_passes(self, host_state, spec_obj):
"""Use information about current vm and task states collected from
compute node statistics to decide whether to filter.
"""
num_io_ops = host_state.num_io_ops
max_io_ops = self._get_max_io_ops_per_host(
host_state, filter_properties)
host_state, spec_obj)
passes = num_io_ops < max_io_ops
if not passes:
LOG.debug("%(host_state)s fails I/O ops check: Max IOs per host "
@ -62,7 +61,7 @@ class AggregateIoOpsFilter(IoOpsFilter):
Fall back to global max_io_ops_per_host if no per-aggregate setting found.
"""
def _get_max_io_ops_per_host(self, host_state, filter_properties):
def _get_max_io_ops_per_host(self, host_state, spec_obj):
aggregate_vals = utils.aggregate_values_from_key(
host_state,
'max_io_ops_per_host')

View File

@ -43,8 +43,7 @@ class MetricsFilter(filters.BaseHostFilter):
name="metrics.weight_setting")
self.keys = set([x[0] for x in opts])
@filters.compat_legacy_props
def host_passes(self, host_state, filter_properties):
def host_passes(self, host_state, spec_obj):
metrics_on_host = set(m.name for m in host_state.metrics)
if not self.keys.issubset(metrics_on_host):
unavail = metrics_on_host - self.keys

View File

@ -12,6 +12,7 @@
import mock
from nova import objects
from nova.scheduler.filters import core_filter
from nova import test
from nova.tests.unit.scheduler import fakes
@ -21,73 +22,73 @@ class TestCoreFilter(test.NoDBTestCase):
def test_core_filter_passes(self):
self.filt_cls = core_filter.CoreFilter()
filter_properties = {'instance_type': {'vcpus': 1}}
spec_obj = objects.RequestSpec(flavor=objects.Flavor(vcpus=1))
host = fakes.FakeHostState('host1', 'node1',
{'vcpus_total': 4, 'vcpus_used': 7,
'cpu_allocation_ratio': 2})
self.assertTrue(self.filt_cls.host_passes(host, filter_properties))
self.assertTrue(self.filt_cls.host_passes(host, spec_obj))
def test_core_filter_fails_safe(self):
self.filt_cls = core_filter.CoreFilter()
filter_properties = {'instance_type': {'vcpus': 1}}
spec_obj = objects.RequestSpec(flavor=objects.Flavor(vcpus=1))
host = fakes.FakeHostState('host1', 'node1', {})
self.assertTrue(self.filt_cls.host_passes(host, filter_properties))
self.assertTrue(self.filt_cls.host_passes(host, spec_obj))
def test_core_filter_fails(self):
self.filt_cls = core_filter.CoreFilter()
filter_properties = {'instance_type': {'vcpus': 1}}
spec_obj = objects.RequestSpec(flavor=objects.Flavor(vcpus=1))
host = fakes.FakeHostState('host1', 'node1',
{'vcpus_total': 4, 'vcpus_used': 8,
'cpu_allocation_ratio': 2})
self.assertFalse(self.filt_cls.host_passes(host, filter_properties))
self.assertFalse(self.filt_cls.host_passes(host, spec_obj))
def test_core_filter_single_instance_overcommit_fails(self):
self.filt_cls = core_filter.CoreFilter()
filter_properties = {'instance_type': {'vcpus': 2}}
spec_obj = objects.RequestSpec(flavor=objects.Flavor(vcpus=2))
host = fakes.FakeHostState('host1', 'node1',
{'vcpus_total': 1, 'vcpus_used': 0,
'cpu_allocation_ratio': 2})
self.assertFalse(self.filt_cls.host_passes(host, filter_properties))
self.assertFalse(self.filt_cls.host_passes(host, spec_obj))
@mock.patch('nova.scheduler.filters.utils.aggregate_values_from_key')
def test_aggregate_core_filter_value_error(self, agg_mock):
self.filt_cls = core_filter.AggregateCoreFilter()
filter_properties = {'context': mock.sentinel.ctx,
'instance_type': {'vcpus': 1}}
spec_obj = objects.RequestSpec(
context=mock.sentinel.ctx, flavor=objects.Flavor(vcpus=1))
host = fakes.FakeHostState('host1', 'node1',
{'vcpus_total': 4, 'vcpus_used': 7,
'cpu_allocation_ratio': 2})
agg_mock.return_value = set(['XXX'])
self.assertTrue(self.filt_cls.host_passes(host, filter_properties))
self.assertTrue(self.filt_cls.host_passes(host, spec_obj))
agg_mock.assert_called_once_with(host, 'cpu_allocation_ratio')
self.assertEqual(4 * 2, host.limits['vcpu'])
@mock.patch('nova.scheduler.filters.utils.aggregate_values_from_key')
def test_aggregate_core_filter_default_value(self, agg_mock):
self.filt_cls = core_filter.AggregateCoreFilter()
filter_properties = {'context': mock.sentinel.ctx,
'instance_type': {'vcpus': 1}}
spec_obj = objects.RequestSpec(
context=mock.sentinel.ctx, flavor=objects.Flavor(vcpus=1))
host = fakes.FakeHostState('host1', 'node1',
{'vcpus_total': 4, 'vcpus_used': 8,
'cpu_allocation_ratio': 2})
agg_mock.return_value = set([])
# False: fallback to default flag w/o aggregates
self.assertFalse(self.filt_cls.host_passes(host, filter_properties))
self.assertFalse(self.filt_cls.host_passes(host, spec_obj))
agg_mock.assert_called_once_with(host, 'cpu_allocation_ratio')
# True: use ratio from aggregates
agg_mock.return_value = set(['3'])
self.assertTrue(self.filt_cls.host_passes(host, filter_properties))
self.assertTrue(self.filt_cls.host_passes(host, spec_obj))
self.assertEqual(4 * 3, host.limits['vcpu'])
@mock.patch('nova.scheduler.filters.utils.aggregate_values_from_key')
def test_aggregate_core_filter_conflict_values(self, agg_mock):
self.filt_cls = core_filter.AggregateCoreFilter()
filter_properties = {'context': mock.sentinel.ctx,
'instance_type': {'vcpus': 1}}
spec_obj = objects.RequestSpec(
context=mock.sentinel.ctx, flavor=objects.Flavor(vcpus=1))
host = fakes.FakeHostState('host1', 'node1',
{'vcpus_total': 4, 'vcpus_used': 8,
'cpu_allocation_ratio': 1})
agg_mock.return_value = set(['2', '3'])
# use the minimum ratio from aggregates
self.assertFalse(self.filt_cls.host_passes(host, filter_properties))
self.assertFalse(self.filt_cls.host_passes(host, spec_obj))
self.assertEqual(4 * 2, host.limits['vcpu'])

View File

@ -12,6 +12,7 @@
import mock
from nova import objects
from nova.scheduler.filters import disk_filter
from nova import test
from nova.tests.unit.scheduler import fakes
@ -25,74 +26,75 @@ class TestDiskFilter(test.NoDBTestCase):
def test_disk_filter_passes(self):
self.flags(disk_allocation_ratio=1.0)
filt_cls = disk_filter.DiskFilter()
filter_properties = {'instance_type': {'root_gb': 1,
'ephemeral_gb': 1, 'swap': 512}}
spec_obj = objects.RequestSpec(
flavor=objects.Flavor(root_gb=1, ephemeral_gb=1, swap=512))
host = fakes.FakeHostState('host1', 'node1',
{'free_disk_mb': 11 * 1024, 'total_usable_disk_gb': 13})
self.assertTrue(filt_cls.host_passes(host, filter_properties))
self.assertTrue(filt_cls.host_passes(host, spec_obj))
def test_disk_filter_fails(self):
self.flags(disk_allocation_ratio=1.0)
filt_cls = disk_filter.DiskFilter()
filter_properties = {'instance_type': {'root_gb': 10,
'ephemeral_gb': 1, 'swap': 1024}}
spec_obj = objects.RequestSpec(
flavor=objects.Flavor(
root_gb=10, ephemeral_gb=1, swap=1024))
host = fakes.FakeHostState('host1', 'node1',
{'free_disk_mb': 11 * 1024, 'total_usable_disk_gb': 13})
self.assertFalse(filt_cls.host_passes(host, filter_properties))
self.assertFalse(filt_cls.host_passes(host, spec_obj))
def test_disk_filter_oversubscribe(self):
self.flags(disk_allocation_ratio=10.0)
filt_cls = disk_filter.DiskFilter()
filter_properties = {'instance_type': {'root_gb': 100,
'ephemeral_gb': 18, 'swap': 1024}}
spec_obj = objects.RequestSpec(
flavor=objects.Flavor(
root_gb=100, ephemeral_gb=18, swap=1024))
# 1GB used... so 119GB allowed...
host = fakes.FakeHostState('host1', 'node1',
{'free_disk_mb': 11 * 1024, 'total_usable_disk_gb': 12})
self.assertTrue(filt_cls.host_passes(host, filter_properties))
self.assertTrue(filt_cls.host_passes(host, spec_obj))
self.assertEqual(12 * 10.0, host.limits['disk_gb'])
def test_disk_filter_oversubscribe_fail(self):
self.flags(disk_allocation_ratio=10.0)
filt_cls = disk_filter.DiskFilter()
filter_properties = {'instance_type': {'root_gb': 100,
'ephemeral_gb': 19, 'swap': 1024}}
spec_obj = objects.RequestSpec(
flavor=objects.Flavor(
root_gb=100, ephemeral_gb=19, swap=1024))
# 1GB used... so 119GB allowed...
host = fakes.FakeHostState('host1', 'node1',
{'free_disk_mb': 11 * 1024, 'total_usable_disk_gb': 12})
self.assertFalse(filt_cls.host_passes(host, filter_properties))
self.assertFalse(filt_cls.host_passes(host, spec_obj))
@mock.patch('nova.scheduler.filters.utils.aggregate_values_from_key')
def test_aggregate_disk_filter_value_error(self, agg_mock):
filt_cls = disk_filter.AggregateDiskFilter()
self.flags(disk_allocation_ratio=1.0)
filter_properties = {
'context': mock.sentinel.ctx,
'instance_type': {'root_gb': 1,
'ephemeral_gb': 1,
'swap': 1024}}
spec_obj = objects.RequestSpec(
context=mock.sentinel.ctx,
flavor=objects.Flavor(
root_gb=1, ephemeral_gb=1, swap=1024))
host = fakes.FakeHostState('host1', 'node1',
{'free_disk_mb': 3 * 1024,
'total_usable_disk_gb': 1})
agg_mock.return_value = set(['XXX'])
self.assertTrue(filt_cls.host_passes(host, filter_properties))
self.assertTrue(filt_cls.host_passes(host, spec_obj))
agg_mock.assert_called_once_with(host, 'disk_allocation_ratio')
@mock.patch('nova.scheduler.filters.utils.aggregate_values_from_key')
def test_aggregate_disk_filter_default_value(self, agg_mock):
filt_cls = disk_filter.AggregateDiskFilter()
self.flags(disk_allocation_ratio=1.0)
filter_properties = {
'context': mock.sentinel.ctx,
'instance_type': {'root_gb': 2,
'ephemeral_gb': 1,
'swap': 1024}}
spec_obj = objects.RequestSpec(
context=mock.sentinel.ctx,
flavor=objects.Flavor(
root_gb=2, ephemeral_gb=1, swap=1024))
host = fakes.FakeHostState('host1', 'node1',
{'free_disk_mb': 3 * 1024,
'total_usable_disk_gb': 1})
# Uses global conf.
agg_mock.return_value = set([])
self.assertFalse(filt_cls.host_passes(host, filter_properties))
self.assertFalse(filt_cls.host_passes(host, spec_obj))
agg_mock.assert_called_once_with(host, 'disk_allocation_ratio')
agg_mock.return_value = set(['2'])
self.assertTrue(filt_cls.host_passes(host, filter_properties))
self.assertTrue(filt_cls.host_passes(host, spec_obj))

View File

@ -10,6 +10,7 @@
# License for the specific language governing permissions and limitations
# under the License.
from nova import objects
from nova.scheduler.filters import exact_core_filter
from nova import test
from nova.tests.unit.scheduler import fakes
@ -22,24 +23,22 @@ class TestExactCoreFilter(test.NoDBTestCase):
self.filt_cls = exact_core_filter.ExactCoreFilter()
def test_exact_core_filter_passes(self):
filter_properties = {'instance_type': {'vcpus': 1}}
spec_obj = objects.RequestSpec(
flavor=objects.Flavor(vcpus=1))
host = self._get_host({'vcpus_total': 3, 'vcpus_used': 2})
self.assertTrue(self.filt_cls.host_passes(host, filter_properties))
self.assertTrue(self.filt_cls.host_passes(host, spec_obj))
def test_exact_core_filter_fails(self):
filter_properties = {'instance_type': {'vcpus': 2}}
spec_obj = objects.RequestSpec(
flavor=objects.Flavor(vcpus=2))
host = self._get_host({'vcpus_total': 3, 'vcpus_used': 2})
self.assertFalse(self.filt_cls.host_passes(host, filter_properties))
def test_exact_core_filter_passes_no_instance_type(self):
filter_properties = {}
host = self._get_host({'vcpus_total': 3, 'vcpus_used': 2})
self.assertTrue(self.filt_cls.host_passes(host, filter_properties))
self.assertFalse(self.filt_cls.host_passes(host, spec_obj))
def test_exact_core_filter_fails_host_vcpus_not_set(self):
filter_properties = {'instance_type': {'vcpus': 1}}
spec_obj = objects.RequestSpec(
flavor=objects.Flavor(vcpus=1))
host = self._get_host({})
self.assertFalse(self.filt_cls.host_passes(host, filter_properties))
self.assertFalse(self.filt_cls.host_passes(host, spec_obj))
def _get_host(self, host_attributes):
return fakes.FakeHostState('host1', 'node1', host_attributes)

View File

@ -10,6 +10,7 @@
# License for the specific language governing permissions and limitations
# under the License.
from nova import objects
from nova.scheduler.filters import exact_disk_filter
from nova import test
from nova.tests.unit.scheduler import fakes
@ -22,26 +23,16 @@ class TestExactDiskFilter(test.NoDBTestCase):
self.filt_cls = exact_disk_filter.ExactDiskFilter()
def test_exact_disk_filter_passes(self):
filter_properties = {
'instance_type': {
'root_gb': 1,
'ephemeral_gb': 1,
'swap': 1024
}
}
spec_obj = objects.RequestSpec(
flavor=objects.Flavor(root_gb=1, ephemeral_gb=1, swap=1024))
host = self._get_host({'free_disk_mb': 3 * 1024})
self.assertTrue(self.filt_cls.host_passes(host, filter_properties))
self.assertTrue(self.filt_cls.host_passes(host, spec_obj))
def test_exact_disk_filter_fails(self):
filter_properties = {
'instance_type': {
'root_gb': 1,
'ephemeral_gb': 1,
'swap': 1024
}
}
spec_obj = objects.RequestSpec(
flavor=objects.Flavor(root_gb=1, ephemeral_gb=1, swap=1024))
host = self._get_host({'free_disk_mb': 2 * 1024})
self.assertFalse(self.filt_cls.host_passes(host, filter_properties))
self.assertFalse(self.filt_cls.host_passes(host, spec_obj))
def _get_host(self, host_attributes):
return fakes.FakeHostState('host1', 'node1', host_attributes)

View File

@ -10,6 +10,7 @@
# License for the specific language governing permissions and limitations
# under the License.
from nova import objects
from nova.scheduler.filters import exact_ram_filter
from nova import test
from nova.tests.unit.scheduler import fakes
@ -22,14 +23,16 @@ class TestRamFilter(test.NoDBTestCase):
self.filt_cls = exact_ram_filter.ExactRamFilter()
def test_exact_ram_filter_passes(self):
filter_properties = {'instance_type': {'memory_mb': 1024}}
spec_obj = objects.RequestSpec(
flavor=objects.Flavor(memory_mb=1024))
host = self._get_host({'free_ram_mb': 1024})
self.assertTrue(self.filt_cls.host_passes(host, filter_properties))
self.assertTrue(self.filt_cls.host_passes(host, spec_obj))
def test_exact_ram_filter_fails(self):
filter_properties = {'instance_type': {'memory_mb': 512}}
spec_obj = objects.RequestSpec(
flavor=objects.Flavor(memory_mb=512))
host = self._get_host({'free_ram_mb': 1024})
self.assertFalse(self.filt_cls.host_passes(host, filter_properties))
self.assertFalse(self.filt_cls.host_passes(host, spec_obj))
def _get_host(self, host_attributes):
return fakes.FakeHostState('host1', 'node1', host_attributes)

View File

@ -13,6 +13,7 @@
import mock
from nova import objects
from nova.scheduler.filters import io_ops_filter
from nova import test
from nova.tests.unit.scheduler import fakes
@ -25,16 +26,16 @@ class TestNumInstancesFilter(test.NoDBTestCase):
self.filt_cls = io_ops_filter.IoOpsFilter()
host = fakes.FakeHostState('host1', 'node1',
{'num_io_ops': 7})
filter_properties = {}
self.assertTrue(self.filt_cls.host_passes(host, filter_properties))
spec_obj = objects.RequestSpec()
self.assertTrue(self.filt_cls.host_passes(host, spec_obj))
def test_filter_num_iops_fails(self):
self.flags(max_io_ops_per_host=8)
self.filt_cls = io_ops_filter.IoOpsFilter()
host = fakes.FakeHostState('host1', 'node1',
{'num_io_ops': 8})
filter_properties = {}
self.assertFalse(self.filt_cls.host_passes(host, filter_properties))
spec_obj = objects.RequestSpec()
self.assertFalse(self.filt_cls.host_passes(host, spec_obj))
@mock.patch('nova.scheduler.filters.utils.aggregate_values_from_key')
def test_aggregate_filter_num_iops_value(self, agg_mock):
@ -42,12 +43,12 @@ class TestNumInstancesFilter(test.NoDBTestCase):
self.filt_cls = io_ops_filter.AggregateIoOpsFilter()
host = fakes.FakeHostState('host1', 'node1',
{'num_io_ops': 7})
filter_properties = {'context': mock.sentinel.ctx}
spec_obj = objects.RequestSpec(context=mock.sentinel.ctx)
agg_mock.return_value = set([])
self.assertFalse(self.filt_cls.host_passes(host, filter_properties))
self.assertFalse(self.filt_cls.host_passes(host, spec_obj))
agg_mock.assert_called_once_with(host, 'max_io_ops_per_host')
agg_mock.return_value = set(['8'])
self.assertTrue(self.filt_cls.host_passes(host, filter_properties))
self.assertTrue(self.filt_cls.host_passes(host, spec_obj))
@mock.patch('nova.scheduler.filters.utils.aggregate_values_from_key')
def test_aggregate_filter_num_iops_value_error(self, agg_mock):
@ -56,6 +57,6 @@ class TestNumInstancesFilter(test.NoDBTestCase):
host = fakes.FakeHostState('host1', 'node1',
{'num_io_ops': 7})
agg_mock.return_value = set(['XXX'])
filter_properties = {'context': mock.sentinel.ctx}
self.assertTrue(self.filt_cls.host_passes(host, filter_properties))
spec_obj = objects.RequestSpec(context=mock.sentinel.ctx)
self.assertTrue(self.filt_cls.host_passes(host, spec_obj))
agg_mock.assert_called_once_with(host, 'max_io_ops_per_host')