diff options
| -rw-r--r-- | nova/scheduler/filters/isolated_hosts_filter.py | 22 | ||||
| -rw-r--r-- | nova/tests/scheduler/test_host_filters.py | 76 |
2 files changed, 63 insertions, 35 deletions
diff --git a/nova/scheduler/filters/isolated_hosts_filter.py b/nova/scheduler/filters/isolated_hosts_filter.py index c8849bcca..fc9884a55 100644 --- a/nova/scheduler/filters/isolated_hosts_filter.py +++ b/nova/scheduler/filters/isolated_hosts_filter.py @@ -33,9 +33,27 @@ class IsolatedHostsFilter(filters.BaseHostFilter): """Returns host.""" def host_passes(self, host_state, filter_properties): + """ + Result Matrix: + | isolated_image | non_isolated_image + -------------+----------------+------------------- + iso_host | True | False + non_iso_host | False | True + + """ + # If the configuration does not list any hosts, the filter will always + # return True, assuming a configuration error, so letting all hosts + # through. + isolated_hosts = CONF.isolated_hosts + isolated_images = CONF.isolated_images + if not isolated_images: + # As there are no images to match, return False if the host is in + # the isolation list + return host_state.host not in isolated_hosts + spec = filter_properties.get('request_spec', {}) props = spec.get('instance_properties', {}) image_ref = props.get('image_ref') - image_isolated = image_ref in CONF.isolated_images - host_isolated = host_state.host in CONF.isolated_hosts + image_isolated = image_ref in isolated_images + host_isolated = host_state.host in isolated_hosts return image_isolated == host_isolated diff --git a/nova/tests/scheduler/test_host_filters.py b/nova/tests/scheduler/test_host_filters.py index 20906051f..7d7c12339 100644 --- a/nova/tests/scheduler/test_host_filters.py +++ b/nova/tests/scheduler/test_host_filters.py @@ -815,49 +815,59 @@ class HostFiltersTestCase(test.TestCase): 'trust:trusted_host': 'true'}, passes=False) - def test_isolated_hosts_fails_isolated_on_non_isolated(self): - self.flags(isolated_images=['isolated'], isolated_hosts=['isolated']) - filt_cls = self.class_map['IsolatedHostsFilter']() + def _do_test_isolated_hosts(self, host_in_list, image_in_list, + set_flags=True): + if set_flags: + self.flags(isolated_images=['isolated_image'], + isolated_hosts=['isolated_host']) + host_name = 'isolated_host' if host_in_list else 'free_host' + image_ref = 'isolated_image' if image_in_list else 'free_image' filter_properties = { 'request_spec': { - 'instance_properties': {'image_ref': 'isolated'} + 'instance_properties': {'image_ref': image_ref} } } - host = fakes.FakeHostState('non-isolated', 'node', {}) - self.assertFalse(filt_cls.host_passes(host, filter_properties)) + filt_cls = self.class_map['IsolatedHostsFilter']() + host = fakes.FakeHostState(host_name, 'node', {}) + return filt_cls.host_passes(host, filter_properties) + + def test_isolated_hosts_fails_isolated_on_non_isolated(self): + self.assertFalse(self._do_test_isolated_hosts(False, True)) def test_isolated_hosts_fails_non_isolated_on_isolated(self): - self.flags(isolated_images=['isolated'], isolated_hosts=['isolated']) - filt_cls = self.class_map['IsolatedHostsFilter']() - filter_properties = { - 'request_spec': { - 'instance_properties': {'image_ref': 'non-isolated'} - } - } - host = fakes.FakeHostState('isolated', 'node', {}) - self.assertFalse(filt_cls.host_passes(host, filter_properties)) + self.assertFalse(self._do_test_isolated_hosts(True, False)) def test_isolated_hosts_passes_isolated_on_isolated(self): - self.flags(isolated_images=['isolated'], isolated_hosts=['isolated']) - filt_cls = self.class_map['IsolatedHostsFilter']() - filter_properties = { - 'request_spec': { - 'instance_properties': {'image_ref': 'isolated'} - } - } - host = fakes.FakeHostState('isolated', 'node', {}) - self.assertTrue(filt_cls.host_passes(host, filter_properties)) + self.assertTrue(self._do_test_isolated_hosts(True, True)) def test_isolated_hosts_passes_non_isolated_on_non_isolated(self): - self.flags(isolated_images=['isolated'], isolated_hosts=['isolated']) - filt_cls = self.class_map['IsolatedHostsFilter']() - filter_properties = { - 'request_spec': { - 'instance_properties': {'image_ref': 'non-isolated'} - } - } - host = fakes.FakeHostState('non-isolated', 'node', {}) - self.assertTrue(filt_cls.host_passes(host, filter_properties)) + self.assertTrue(self._do_test_isolated_hosts(False, False)) + + def test_isolated_hosts_no_config(self): + # If there are no hosts nor isolated images in the config, it should + # not filter at all. This is the default config. + self.assertTrue(self._do_test_isolated_hosts(False, True, False)) + self.assertTrue(self._do_test_isolated_hosts(True, False, False)) + self.assertTrue(self._do_test_isolated_hosts(True, True, False)) + self.assertTrue(self._do_test_isolated_hosts(False, False, False)) + + def test_isolated_hosts_no_hosts_config(self): + self.flags(isolated_images=['isolated_image']) + # If there are no hosts in the config, it should only filter out + # images that are listed + self.assertFalse(self._do_test_isolated_hosts(False, True, False)) + self.assertTrue(self._do_test_isolated_hosts(True, False, False)) + self.assertFalse(self._do_test_isolated_hosts(True, True, False)) + self.assertTrue(self._do_test_isolated_hosts(False, False, False)) + + def test_isolated_hosts_no_images_config(self): + self.flags(isolated_hosts=['isolated_host']) + # If there are no images in the config, it should only filter out + # isolated_hosts + self.assertTrue(self._do_test_isolated_hosts(False, True, False)) + self.assertFalse(self._do_test_isolated_hosts(True, False, False)) + self.assertFalse(self._do_test_isolated_hosts(True, True, False)) + self.assertTrue(self._do_test_isolated_hosts(False, False, False)) def test_json_filter_passes(self): filt_cls = self.class_map['JsonFilter']() |
