Merge "Modify metric-related filters for RequestSpec"

This commit is contained in:
Jenkins 2015-12-10 14:59:08 +00:00 committed by Gerrit Code Review
commit 240df42859
13 changed files with 106 additions and 127 deletions

View File

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

View File

@ -28,22 +28,20 @@ CONF = nova.conf.CONF
class DiskFilter(filters.BaseHostFilter): class DiskFilter(filters.BaseHostFilter):
"""Disk Filter with over subscription flag.""" """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 return CONF.disk_allocation_ratio
@filters.compat_legacy_props def host_passes(self, host_state, spec_obj):
def host_passes(self, host_state, filter_properties):
"""Filter based on disk usage.""" """Filter based on disk usage."""
instance_type = filter_properties.get('instance_type') requested_disk = (1024 * (spec_obj.root_gb +
requested_disk = (1024 * (instance_type['root_gb'] + spec_obj.ephemeral_gb) +
instance_type['ephemeral_gb']) + spec_obj.swap)
instance_type['swap'])
free_disk_mb = host_state.free_disk_mb free_disk_mb = host_state.free_disk_mb
total_usable_disk_mb = host_state.total_usable_disk_gb * 1024 total_usable_disk_mb = host_state.total_usable_disk_gb * 1024
disk_allocation_ratio = self._get_disk_allocation_ratio( 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 disk_mb_limit = total_usable_disk_mb * disk_allocation_ratio
used_disk_mb = total_usable_disk_mb - free_disk_mb used_disk_mb = total_usable_disk_mb - free_disk_mb
@ -69,7 +67,7 @@ class AggregateDiskFilter(DiskFilter):
found. 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( aggregate_vals = utils.aggregate_values_from_key(
host_state, host_state,
'disk_allocation_ratio') 'disk_allocation_ratio')

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -12,6 +12,7 @@
import mock import mock
from nova import objects
from nova.scheduler.filters import disk_filter from nova.scheduler.filters import disk_filter
from nova import test from nova import test
from nova.tests.unit.scheduler import fakes from nova.tests.unit.scheduler import fakes
@ -25,74 +26,75 @@ class TestDiskFilter(test.NoDBTestCase):
def test_disk_filter_passes(self): def test_disk_filter_passes(self):
self.flags(disk_allocation_ratio=1.0) self.flags(disk_allocation_ratio=1.0)
filt_cls = disk_filter.DiskFilter() filt_cls = disk_filter.DiskFilter()
filter_properties = {'instance_type': {'root_gb': 1, spec_obj = objects.RequestSpec(
'ephemeral_gb': 1, 'swap': 512}} flavor=objects.Flavor(root_gb=1, ephemeral_gb=1, swap=512))
host = fakes.FakeHostState('host1', 'node1', host = fakes.FakeHostState('host1', 'node1',
{'free_disk_mb': 11 * 1024, 'total_usable_disk_gb': 13}) {'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): def test_disk_filter_fails(self):
self.flags(disk_allocation_ratio=1.0) self.flags(disk_allocation_ratio=1.0)
filt_cls = disk_filter.DiskFilter() filt_cls = disk_filter.DiskFilter()
filter_properties = {'instance_type': {'root_gb': 10, spec_obj = objects.RequestSpec(
'ephemeral_gb': 1, 'swap': 1024}} flavor=objects.Flavor(
root_gb=10, ephemeral_gb=1, swap=1024))
host = fakes.FakeHostState('host1', 'node1', host = fakes.FakeHostState('host1', 'node1',
{'free_disk_mb': 11 * 1024, 'total_usable_disk_gb': 13}) {'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): def test_disk_filter_oversubscribe(self):
self.flags(disk_allocation_ratio=10.0) self.flags(disk_allocation_ratio=10.0)
filt_cls = disk_filter.DiskFilter() filt_cls = disk_filter.DiskFilter()
filter_properties = {'instance_type': {'root_gb': 100, spec_obj = objects.RequestSpec(
'ephemeral_gb': 18, 'swap': 1024}} flavor=objects.Flavor(
root_gb=100, ephemeral_gb=18, swap=1024))
# 1GB used... so 119GB allowed... # 1GB used... so 119GB allowed...
host = fakes.FakeHostState('host1', 'node1', host = fakes.FakeHostState('host1', 'node1',
{'free_disk_mb': 11 * 1024, 'total_usable_disk_gb': 12}) {'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']) self.assertEqual(12 * 10.0, host.limits['disk_gb'])
def test_disk_filter_oversubscribe_fail(self): def test_disk_filter_oversubscribe_fail(self):
self.flags(disk_allocation_ratio=10.0) self.flags(disk_allocation_ratio=10.0)
filt_cls = disk_filter.DiskFilter() filt_cls = disk_filter.DiskFilter()
filter_properties = {'instance_type': {'root_gb': 100, spec_obj = objects.RequestSpec(
'ephemeral_gb': 19, 'swap': 1024}} flavor=objects.Flavor(
root_gb=100, ephemeral_gb=19, swap=1024))
# 1GB used... so 119GB allowed... # 1GB used... so 119GB allowed...
host = fakes.FakeHostState('host1', 'node1', host = fakes.FakeHostState('host1', 'node1',
{'free_disk_mb': 11 * 1024, 'total_usable_disk_gb': 12}) {'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') @mock.patch('nova.scheduler.filters.utils.aggregate_values_from_key')
def test_aggregate_disk_filter_value_error(self, agg_mock): def test_aggregate_disk_filter_value_error(self, agg_mock):
filt_cls = disk_filter.AggregateDiskFilter() filt_cls = disk_filter.AggregateDiskFilter()
self.flags(disk_allocation_ratio=1.0) self.flags(disk_allocation_ratio=1.0)
filter_properties = { spec_obj = objects.RequestSpec(
'context': mock.sentinel.ctx, context=mock.sentinel.ctx,
'instance_type': {'root_gb': 1, flavor=objects.Flavor(
'ephemeral_gb': 1, root_gb=1, ephemeral_gb=1, swap=1024))
'swap': 1024}}
host = fakes.FakeHostState('host1', 'node1', host = fakes.FakeHostState('host1', 'node1',
{'free_disk_mb': 3 * 1024, {'free_disk_mb': 3 * 1024,
'total_usable_disk_gb': 1}) 'total_usable_disk_gb': 1})
agg_mock.return_value = set(['XXX']) 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') agg_mock.assert_called_once_with(host, 'disk_allocation_ratio')
@mock.patch('nova.scheduler.filters.utils.aggregate_values_from_key') @mock.patch('nova.scheduler.filters.utils.aggregate_values_from_key')
def test_aggregate_disk_filter_default_value(self, agg_mock): def test_aggregate_disk_filter_default_value(self, agg_mock):
filt_cls = disk_filter.AggregateDiskFilter() filt_cls = disk_filter.AggregateDiskFilter()
self.flags(disk_allocation_ratio=1.0) self.flags(disk_allocation_ratio=1.0)
filter_properties = { spec_obj = objects.RequestSpec(
'context': mock.sentinel.ctx, context=mock.sentinel.ctx,
'instance_type': {'root_gb': 2, flavor=objects.Flavor(
'ephemeral_gb': 1, root_gb=2, ephemeral_gb=1, swap=1024))
'swap': 1024}}
host = fakes.FakeHostState('host1', 'node1', host = fakes.FakeHostState('host1', 'node1',
{'free_disk_mb': 3 * 1024, {'free_disk_mb': 3 * 1024,
'total_usable_disk_gb': 1}) 'total_usable_disk_gb': 1})
# Uses global conf. # Uses global conf.
agg_mock.return_value = set([]) 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.assert_called_once_with(host, 'disk_allocation_ratio')
agg_mock.return_value = set(['2']) 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 # License for the specific language governing permissions and limitations
# under the License. # under the License.
from nova import objects
from nova.scheduler.filters import exact_core_filter from nova.scheduler.filters import exact_core_filter
from nova import test from nova import test
from nova.tests.unit.scheduler import fakes from nova.tests.unit.scheduler import fakes
@ -22,24 +23,22 @@ class TestExactCoreFilter(test.NoDBTestCase):
self.filt_cls = exact_core_filter.ExactCoreFilter() self.filt_cls = exact_core_filter.ExactCoreFilter()
def test_exact_core_filter_passes(self): 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}) 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): 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}) host = self._get_host({'vcpus_total': 3, 'vcpus_used': 2})
self.assertFalse(self.filt_cls.host_passes(host, filter_properties)) self.assertFalse(self.filt_cls.host_passes(host, spec_obj))
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))
def test_exact_core_filter_fails_host_vcpus_not_set(self): 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({}) 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): def _get_host(self, host_attributes):
return fakes.FakeHostState('host1', 'node1', host_attributes) return fakes.FakeHostState('host1', 'node1', host_attributes)

View File

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

View File

@ -10,6 +10,7 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from nova import objects
from nova.scheduler.filters import exact_ram_filter from nova.scheduler.filters import exact_ram_filter
from nova import test from nova import test
from nova.tests.unit.scheduler import fakes from nova.tests.unit.scheduler import fakes
@ -22,14 +23,16 @@ class TestRamFilter(test.NoDBTestCase):
self.filt_cls = exact_ram_filter.ExactRamFilter() self.filt_cls = exact_ram_filter.ExactRamFilter()
def test_exact_ram_filter_passes(self): 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}) 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): 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}) 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): def _get_host(self, host_attributes):
return fakes.FakeHostState('host1', 'node1', host_attributes) return fakes.FakeHostState('host1', 'node1', host_attributes)

View File

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