Modify metric-related filters for RequestSpec
Change-Id: I81762f3bbb022e3d3b85c17eaaf6392639753e08 Partially-Implements: blueprint request-spec-object-mitaka
This commit is contained in:
parent
e792d50efa
commit
7358b68d07
|
@ -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')
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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 "
|
||||
|
|
|
@ -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 "
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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'])
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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')
|
||||
|
|
Loading…
Reference in New Issue