Fixing a bunch of conflicts
This commit is contained in:
@@ -14,8 +14,8 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Host Filter is a driver mechanism for requesting instance resources.
|
Host Filter is a mechanism for requesting instance resources.
|
||||||
Three drivers are included: AllHosts, Flavor & JSON. AllHosts just
|
Three filters are included: AllHosts, Flavor & JSON. AllHosts just
|
||||||
returns the full, unfiltered list of hosts. Flavor is a hard coded
|
returns the full, unfiltered list of hosts. Flavor is a hard coded
|
||||||
matching mechanism based on flavor criteria and JSON is an ad-hoc
|
matching mechanism based on flavor criteria and JSON is an ad-hoc
|
||||||
filter grammar.
|
filter grammar.
|
||||||
@@ -43,17 +43,18 @@ from nova import flags
|
|||||||
from nova import log as logging
|
from nova import log as logging
|
||||||
from nova.scheduler import zone_aware_scheduler
|
from nova.scheduler import zone_aware_scheduler
|
||||||
from nova import utils
|
from nova import utils
|
||||||
|
from nova.scheduler import zone_aware_scheduler
|
||||||
|
|
||||||
LOG = logging.getLogger('nova.scheduler.host_filter')
|
LOG = logging.getLogger('nova.scheduler.host_filter')
|
||||||
|
|
||||||
FLAGS = flags.FLAGS
|
FLAGS = flags.FLAGS
|
||||||
flags.DEFINE_string('default_host_filter_driver',
|
flags.DEFINE_string('default_host_filter',
|
||||||
'nova.scheduler.host_filter.AllHostsFilter',
|
'nova.scheduler.host_filter.AllHostsFilter',
|
||||||
'Which driver to use for filtering hosts.')
|
'Which filter to use for filtering hosts.')
|
||||||
|
|
||||||
|
|
||||||
class HostFilter(object):
|
class HostFilter(object):
|
||||||
"""Base class for host filter drivers."""
|
"""Base class for host filters."""
|
||||||
|
|
||||||
def instance_type_to_filter(self, instance_type):
|
def instance_type_to_filter(self, instance_type):
|
||||||
"""Convert instance_type into a filter for most common use-case."""
|
"""Convert instance_type into a filter for most common use-case."""
|
||||||
@@ -64,14 +65,15 @@ class HostFilter(object):
|
|||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
def _full_name(self):
|
def _full_name(self):
|
||||||
"""module.classname of the filter driver"""
|
"""module.classname of the filter."""
|
||||||
return "%s.%s" % (self.__module__, self.__class__.__name__)
|
return "%s.%s" % (self.__module__, self.__class__.__name__)
|
||||||
|
|
||||||
|
|
||||||
class AllHostsFilter(HostFilter):
|
class AllHostsFilter(HostFilter):
|
||||||
"""NOP host filter driver. Returns all hosts in ZoneManager.
|
""" NOP host filter. Returns all hosts in ZoneManager.
|
||||||
This essentially does what the old Scheduler+Chance used
|
This essentially does what the old Scheduler+Chance used
|
||||||
to give us."""
|
to give us.
|
||||||
|
"""
|
||||||
|
|
||||||
def instance_type_to_filter(self, instance_type):
|
def instance_type_to_filter(self, instance_type):
|
||||||
"""Return anything to prevent base-class from raising
|
"""Return anything to prevent base-class from raising
|
||||||
@@ -85,7 +87,7 @@ class AllHostsFilter(HostFilter):
|
|||||||
|
|
||||||
|
|
||||||
class InstanceTypeFilter(HostFilter):
|
class InstanceTypeFilter(HostFilter):
|
||||||
"""HostFilter driver hard-coded to work with InstanceType records."""
|
"""HostFilter hard-coded to work with InstanceType records."""
|
||||||
|
|
||||||
def instance_type_to_filter(self, instance_type):
|
def instance_type_to_filter(self, instance_type):
|
||||||
"""Use instance_type to filter hosts."""
|
"""Use instance_type to filter hosts."""
|
||||||
@@ -133,8 +135,9 @@ class InstanceTypeFilter(HostFilter):
|
|||||||
|
|
||||||
|
|
||||||
class JsonFilter(HostFilter):
|
class JsonFilter(HostFilter):
|
||||||
"""Host Filter driver to allow simple JSON-based grammar for
|
"""Host Filter to allow simple JSON-based grammar for
|
||||||
selecting hosts."""
|
selecting hosts.
|
||||||
|
"""
|
||||||
|
|
||||||
def _equals(self, args):
|
def _equals(self, args):
|
||||||
"""First term is == all the other terms."""
|
"""First term is == all the other terms."""
|
||||||
@@ -230,7 +233,8 @@ class JsonFilter(HostFilter):
|
|||||||
|
|
||||||
def _parse_string(self, string, host, services):
|
def _parse_string(self, string, host, services):
|
||||||
"""Strings prefixed with $ are capability lookups in the
|
"""Strings prefixed with $ are capability lookups in the
|
||||||
form '$service.capability[.subcap*]'"""
|
form '$service.capability[.subcap*]'
|
||||||
|
"""
|
||||||
if not string:
|
if not string:
|
||||||
return None
|
return None
|
||||||
if string[0] != '$':
|
if string[0] != '$':
|
||||||
@@ -273,43 +277,48 @@ class JsonFilter(HostFilter):
|
|||||||
return hosts
|
return hosts
|
||||||
|
|
||||||
|
|
||||||
DRIVERS = [AllHostsFilter, InstanceTypeFilter, JsonFilter]
|
FILTERS = [AllHostsFilter, InstanceTypeFilter, JsonFilter]
|
||||||
|
|
||||||
|
|
||||||
def choose_driver(driver_name=None):
|
def choose_host_filter(filter_name=None):
|
||||||
"""Since the caller may specify which driver to use we need
|
"""Since the caller may specify which filter to use we need
|
||||||
to have an authoritative list of what is permissible. This
|
to have an authoritative list of what is permissible. This
|
||||||
function checks the driver name against a predefined set
|
function checks the filter name against a predefined set
|
||||||
of acceptable drivers."""
|
of acceptable filters.
|
||||||
|
"""
|
||||||
|
|
||||||
if not driver_name:
|
if not filter_name:
|
||||||
driver_name = FLAGS.default_host_filter_driver
|
filter_name = FLAGS.default_host_filter
|
||||||
|
for filter_class in FILTERS:
|
||||||
try:
|
host_match = "%s.%s" % (filter_class.__module__, filter_class.__name__)
|
||||||
driver = utils.import_object(driver_name)
|
if host_match == filter_name:
|
||||||
return driver
|
return filter_class()
|
||||||
except exception.ClassNotFound:
|
raise exception.SchedulerHostFilterNotFound(filter_name=filter_name)
|
||||||
raise exception.SchedulerHostFilterDriverNotFound(
|
|
||||||
driver_name=driver_name)
|
|
||||||
|
|
||||||
|
|
||||||
class HostFilterScheduler(zone_aware_scheduler.ZoneAwareScheduler):
|
class HostFilterScheduler(zone_aware_scheduler.ZoneAwareScheduler):
|
||||||
"""The HostFilterScheduler uses the HostFilter drivers to filter
|
"""The HostFilterScheduler uses the HostFilter to filter
|
||||||
hosts for weighing. The particular driver used may be passed in
|
hosts for weighing. The particular filter used may be passed in
|
||||||
as an argument or the default will be used.
|
as an argument or the default will be used.
|
||||||
|
|
||||||
request_spec = {'filter_driver': <Filter Driver name>,
|
request_spec = {'filter': <Filter name>,
|
||||||
'instance_type': <InstanceType dict>}
|
'instance_type': <InstanceType dict>}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def filter_hosts(self, num, request_spec):
|
def filter_hosts(self, num, request_spec):
|
||||||
"""Filter the full host list (from the ZoneManager)"""
|
"""Filter the full host list (from the ZoneManager)"""
|
||||||
driver_name = request_spec.get('filter_driver', None)
|
filter_name = request_spec.get('filter', None)
|
||||||
driver = choose_driver(driver_name)
|
host_filter = choose_host_filter(filter_name)
|
||||||
|
|
||||||
# TODO(sandy): We're only using InstanceType-based specs
|
# TODO(sandy): We're only using InstanceType-based specs
|
||||||
# currently. Later we'll need to snoop for more detailed
|
# currently. Later we'll need to snoop for more detailed
|
||||||
# host filter requests.
|
# host filter requests.
|
||||||
instance_type = request_spec['instance_type']
|
instance_type = request_spec['instance_type']
|
||||||
name, query = driver.instance_type_to_filter(instance_type)
|
name, query = host_filter.instance_type_to_filter(instance_type)
|
||||||
return driver.filter_hosts(self.zone_manager, query)
|
return host_filter.filter_hosts(self.zone_manager, query)
|
||||||
|
|
||||||
|
def weigh_hosts(self, num, request_spec, hosts):
|
||||||
|
"""Derived classes must override this method and return
|
||||||
|
a lists of hosts in [{weight, hostname}] format.
|
||||||
|
"""
|
||||||
|
return [dict(weight=1, hostname=host) for host, caps in hosts]
|
||||||
|
|||||||
@@ -23,8 +23,8 @@ across zones. There are two expansion points to this class for:
|
|||||||
import operator
|
import operator
|
||||||
|
|
||||||
from nova import db
|
from nova import db
|
||||||
from nova import rpc
|
|
||||||
from nova import log as logging
|
from nova import log as logging
|
||||||
|
from nova import rpc
|
||||||
from nova.scheduler import api
|
from nova.scheduler import api
|
||||||
from nova.scheduler import driver
|
from nova.scheduler import driver
|
||||||
|
|
||||||
@@ -43,12 +43,11 @@ class ZoneAwareScheduler(driver.Scheduler):
|
|||||||
"""This method is called from nova.compute.api to provision
|
"""This method is called from nova.compute.api to provision
|
||||||
an instance. However we need to look at the parameters being
|
an instance. However we need to look at the parameters being
|
||||||
passed in to see if this is a request to:
|
passed in to see if this is a request to:
|
||||||
|
|
||||||
1. Create a Build Plan and then provision, or
|
1. Create a Build Plan and then provision, or
|
||||||
|
|
||||||
2. Use the Build Plan information in the request parameters
|
2. Use the Build Plan information in the request parameters
|
||||||
to simply create the instance (either in this zone or
|
to simply create the instance (either in this zone or
|
||||||
a child zone)."""
|
a child zone).
|
||||||
|
"""
|
||||||
|
|
||||||
# TODO(sandy): We'll have to look for richer specs at some point.
|
# TODO(sandy): We'll have to look for richer specs at some point.
|
||||||
|
|
||||||
@@ -81,15 +80,15 @@ class ZoneAwareScheduler(driver.Scheduler):
|
|||||||
% locals())
|
% locals())
|
||||||
else:
|
else:
|
||||||
# TODO(sandy) Provision in child zone ...
|
# TODO(sandy) Provision in child zone ...
|
||||||
LOG.warning(_("Provision to Child Zone not supported (yet)")
|
LOG.warning(_("Provision to Child Zone not supported (yet)"))
|
||||||
% locals())
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def select(self, context, request_spec, *args, **kwargs):
|
def select(self, context, request_spec, *args, **kwargs):
|
||||||
"""Select returns a list of weights and zone/host information
|
"""Select returns a list of weights and zone/host information
|
||||||
corresponding to the best hosts to service the request. Any
|
corresponding to the best hosts to service the request. Any
|
||||||
child zone information has been encrypted so as not to reveal
|
child zone information has been encrypted so as not to reveal
|
||||||
anything about the children."""
|
anything about the children.
|
||||||
|
"""
|
||||||
return self._schedule(context, "compute", request_spec,
|
return self._schedule(context, "compute", request_spec,
|
||||||
*args, **kwargs)
|
*args, **kwargs)
|
||||||
|
|
||||||
@@ -143,7 +142,8 @@ class ZoneAwareScheduler(driver.Scheduler):
|
|||||||
|
|
||||||
def filter_hosts(self, num, request_spec):
|
def filter_hosts(self, num, request_spec):
|
||||||
"""Derived classes must override this method and return
|
"""Derived classes must override this method and return
|
||||||
a list of hosts in [(hostname, capability_dict)] format."""
|
a list of hosts in [(hostname, capability_dict)] format.
|
||||||
|
"""
|
||||||
# NOTE(sirp): The default logic is the equivalent to AllHostsFilter
|
# NOTE(sirp): The default logic is the equivalent to AllHostsFilter
|
||||||
service_states = self.zone_manager.service_states
|
service_states = self.zone_manager.service_states
|
||||||
return [(host, services)
|
return [(host, services)
|
||||||
@@ -151,6 +151,7 @@ class ZoneAwareScheduler(driver.Scheduler):
|
|||||||
|
|
||||||
def weigh_hosts(self, num, request_spec, hosts):
|
def weigh_hosts(self, num, request_spec, hosts):
|
||||||
"""Derived classes may override this to provide more sophisticated
|
"""Derived classes may override this to provide more sophisticated
|
||||||
scheduling objectives"""
|
scheduling objectives
|
||||||
|
"""
|
||||||
# NOTE(sirp): The default logic is the same as the NoopCostFunction
|
# NOTE(sirp): The default logic is the same as the NoopCostFunction
|
||||||
return [dict(weight=1, hostname=host) for host, caps in hosts]
|
return [dict(weight=1, hostname=host) for host, caps in hosts]
|
||||||
|
|||||||
@@ -13,7 +13,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.
|
||||||
"""
|
"""
|
||||||
Tests For Scheduler Host Filter Drivers.
|
Tests For Scheduler Host Filters.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import json
|
import json
|
||||||
@@ -22,18 +22,43 @@ from nova import exception
|
|||||||
from nova import flags
|
from nova import flags
|
||||||
from nova import test
|
from nova import test
|
||||||
from nova.scheduler import host_filter
|
from nova.scheduler import host_filter
|
||||||
from nova.tests.scheduler import test_zone_aware_scheduler
|
|
||||||
|
|
||||||
FLAGS = flags.FLAGS
|
FLAGS = flags.FLAGS
|
||||||
|
|
||||||
|
|
||||||
|
class FakeZoneManager:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class HostFilterTestCase(test.TestCase):
|
class HostFilterTestCase(test.TestCase):
|
||||||
"""Test case for host filter drivers."""
|
"""Test case for host filters."""
|
||||||
|
|
||||||
|
def _host_caps(self, multiplier):
|
||||||
|
# Returns host capabilities in the following way:
|
||||||
|
# host1 = memory:free 10 (100max)
|
||||||
|
# disk:available 100 (1000max)
|
||||||
|
# hostN = memory:free 10 + 10N
|
||||||
|
# disk:available 100 + 100N
|
||||||
|
# in other words: hostN has more resources than host0
|
||||||
|
# which means ... don't go above 10 hosts.
|
||||||
|
return {'host_name-description': 'XenServer %s' % multiplier,
|
||||||
|
'host_hostname': 'xs-%s' % multiplier,
|
||||||
|
'host_memory_total': 100,
|
||||||
|
'host_memory_overhead': 10,
|
||||||
|
'host_memory_free': 10 + multiplier * 10,
|
||||||
|
'host_memory_free-computed': 10 + multiplier * 10,
|
||||||
|
'host_other-config': {},
|
||||||
|
'host_ip_address': '192.168.1.%d' % (100 + multiplier),
|
||||||
|
'host_cpu_info': {},
|
||||||
|
'disk_available': 100 + multiplier * 100,
|
||||||
|
'disk_total': 1000,
|
||||||
|
'disk_used': 0,
|
||||||
|
'host_uuid': 'xxx-%d' % multiplier,
|
||||||
|
'host_name-label': 'xs-%s' % multiplier}
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(HostFilterTestCase, self).setUp()
|
self.old_flag = FLAGS.default_host_filter
|
||||||
self.old_flag = FLAGS.default_host_filter_driver
|
FLAGS.default_host_filter = \
|
||||||
FLAGS.default_host_filter_driver = \
|
|
||||||
'nova.scheduler.host_filter.AllHostsFilter'
|
'nova.scheduler.host_filter.AllHostsFilter'
|
||||||
self.instance_type = dict(name='tiny',
|
self.instance_type = dict(name='tiny',
|
||||||
memory_mb=50,
|
memory_mb=50,
|
||||||
@@ -44,63 +69,59 @@ class HostFilterTestCase(test.TestCase):
|
|||||||
rxtx_quota=30000,
|
rxtx_quota=30000,
|
||||||
rxtx_cap=200)
|
rxtx_cap=200)
|
||||||
|
|
||||||
class FakeZoneManager:
|
|
||||||
pass
|
|
||||||
|
|
||||||
self.zone_manager = FakeZoneManager()
|
self.zone_manager = FakeZoneManager()
|
||||||
|
states = {}
|
||||||
states = test_zone_aware_scheduler.fake_zone_manager_service_states(
|
for x in xrange(10):
|
||||||
num_hosts=10)
|
states['host%02d' % (x + 1)] = {'compute': self._host_caps(x)}
|
||||||
self.zone_manager.service_states = states
|
self.zone_manager.service_states = states
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
FLAGS.default_host_filter_driver = self.old_flag
|
FLAGS.default_host_filter = self.old_flag
|
||||||
super(HostFilterTestCase, self).tearDown()
|
|
||||||
|
|
||||||
def test_choose_driver(self):
|
def test_choose_filter(self):
|
||||||
# Test default driver ...
|
# Test default filter ...
|
||||||
driver = host_filter.choose_driver()
|
hf = host_filter.choose_host_filter()
|
||||||
self.assertEquals(driver._full_name(),
|
self.assertEquals(hf._full_name(),
|
||||||
'nova.scheduler.host_filter.AllHostsFilter')
|
'nova.scheduler.host_filter.AllHostsFilter')
|
||||||
# Test valid driver ...
|
# Test valid filter ...
|
||||||
driver = host_filter.choose_driver(
|
hf = host_filter.choose_host_filter(
|
||||||
'nova.scheduler.host_filter.InstanceTypeFilter')
|
'nova.scheduler.host_filter.InstanceTypeFilter')
|
||||||
self.assertEquals(driver._full_name(),
|
self.assertEquals(hf._full_name(),
|
||||||
'nova.scheduler.host_filter.InstanceTypeFilter')
|
'nova.scheduler.host_filter.InstanceTypeFilter')
|
||||||
# Test invalid driver ...
|
# Test invalid filter ...
|
||||||
try:
|
try:
|
||||||
host_filter.choose_driver('does not exist')
|
host_filter.choose_host_filter('does not exist')
|
||||||
self.fail("Should not find driver")
|
self.fail("Should not find host filter.")
|
||||||
except exception.SchedulerHostFilterDriverNotFound:
|
except exception.SchedulerHostFilterNotFound:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def test_all_host_driver(self):
|
def test_all_host_filter(self):
|
||||||
driver = host_filter.AllHostsFilter()
|
hf = host_filter.AllHostsFilter()
|
||||||
cooked = driver.instance_type_to_filter(self.instance_type)
|
cooked = hf.instance_type_to_filter(self.instance_type)
|
||||||
hosts = driver.filter_hosts(self.zone_manager, cooked)
|
hosts = hf.filter_hosts(self.zone_manager, cooked)
|
||||||
self.assertEquals(10, len(hosts))
|
self.assertEquals(10, len(hosts))
|
||||||
for host, capabilities in hosts:
|
for host, capabilities in hosts:
|
||||||
self.assertTrue(host.startswith('host'))
|
self.assertTrue(host.startswith('host'))
|
||||||
|
|
||||||
def test_instance_type_driver(self):
|
def test_instance_type_filter(self):
|
||||||
driver = host_filter.InstanceTypeFilter()
|
hf = host_filter.InstanceTypeFilter()
|
||||||
# filter all hosts that can support 50 ram and 500 disk
|
# filter all hosts that can support 50 ram and 500 disk
|
||||||
name, cooked = driver.instance_type_to_filter(self.instance_type)
|
name, cooked = hf.instance_type_to_filter(self.instance_type)
|
||||||
self.assertEquals('nova.scheduler.host_filter.InstanceTypeFilter',
|
self.assertEquals('nova.scheduler.host_filter.InstanceTypeFilter',
|
||||||
name)
|
name)
|
||||||
hosts = driver.filter_hosts(self.zone_manager, cooked)
|
hosts = hf.filter_hosts(self.zone_manager, cooked)
|
||||||
self.assertEquals(6, len(hosts))
|
self.assertEquals(6, len(hosts))
|
||||||
just_hosts = [host for host, caps in hosts]
|
just_hosts = [host for host, caps in hosts]
|
||||||
just_hosts.sort()
|
just_hosts.sort()
|
||||||
self.assertEquals('host05', just_hosts[0])
|
self.assertEquals('host05', just_hosts[0])
|
||||||
self.assertEquals('host10', just_hosts[5])
|
self.assertEquals('host10', just_hosts[5])
|
||||||
|
|
||||||
def test_json_driver(self):
|
def test_json_filter(self):
|
||||||
driver = host_filter.JsonFilter()
|
hf = host_filter.JsonFilter()
|
||||||
# filter all hosts that can support 50 ram and 500 disk
|
# filter all hosts that can support 50 ram and 500 disk
|
||||||
name, cooked = driver.instance_type_to_filter(self.instance_type)
|
name, cooked = hf.instance_type_to_filter(self.instance_type)
|
||||||
self.assertEquals('nova.scheduler.host_filter.JsonFilter', name)
|
self.assertEquals('nova.scheduler.host_filter.JsonFilter', name)
|
||||||
hosts = driver.filter_hosts(self.zone_manager, cooked)
|
hosts = hf.filter_hosts(self.zone_manager, cooked)
|
||||||
self.assertEquals(6, len(hosts))
|
self.assertEquals(6, len(hosts))
|
||||||
just_hosts = [host for host, caps in hosts]
|
just_hosts = [host for host, caps in hosts]
|
||||||
just_hosts.sort()
|
just_hosts.sort()
|
||||||
@@ -120,7 +141,7 @@ class HostFilterTestCase(test.TestCase):
|
|||||||
]
|
]
|
||||||
]
|
]
|
||||||
cooked = json.dumps(raw)
|
cooked = json.dumps(raw)
|
||||||
hosts = driver.filter_hosts(self.zone_manager, cooked)
|
hosts = hf.filter_hosts(self.zone_manager, cooked)
|
||||||
|
|
||||||
self.assertEquals(5, len(hosts))
|
self.assertEquals(5, len(hosts))
|
||||||
just_hosts = [host for host, caps in hosts]
|
just_hosts = [host for host, caps in hosts]
|
||||||
@@ -132,7 +153,7 @@ class HostFilterTestCase(test.TestCase):
|
|||||||
['=', '$compute.host_memory_free', 30],
|
['=', '$compute.host_memory_free', 30],
|
||||||
]
|
]
|
||||||
cooked = json.dumps(raw)
|
cooked = json.dumps(raw)
|
||||||
hosts = driver.filter_hosts(self.zone_manager, cooked)
|
hosts = hf.filter_hosts(self.zone_manager, cooked)
|
||||||
|
|
||||||
self.assertEquals(9, len(hosts))
|
self.assertEquals(9, len(hosts))
|
||||||
just_hosts = [host for host, caps in hosts]
|
just_hosts = [host for host, caps in hosts]
|
||||||
@@ -142,7 +163,7 @@ class HostFilterTestCase(test.TestCase):
|
|||||||
|
|
||||||
raw = ['in', '$compute.host_memory_free', 20, 40, 60, 80, 100]
|
raw = ['in', '$compute.host_memory_free', 20, 40, 60, 80, 100]
|
||||||
cooked = json.dumps(raw)
|
cooked = json.dumps(raw)
|
||||||
hosts = driver.filter_hosts(self.zone_manager, cooked)
|
hosts = hf.filter_hosts(self.zone_manager, cooked)
|
||||||
|
|
||||||
self.assertEquals(5, len(hosts))
|
self.assertEquals(5, len(hosts))
|
||||||
just_hosts = [host for host, caps in hosts]
|
just_hosts = [host for host, caps in hosts]
|
||||||
@@ -154,35 +175,32 @@ class HostFilterTestCase(test.TestCase):
|
|||||||
raw = ['unknown command', ]
|
raw = ['unknown command', ]
|
||||||
cooked = json.dumps(raw)
|
cooked = json.dumps(raw)
|
||||||
try:
|
try:
|
||||||
driver.filter_hosts(self.zone_manager, cooked)
|
hf.filter_hosts(self.zone_manager, cooked)
|
||||||
self.fail("Should give KeyError")
|
self.fail("Should give KeyError")
|
||||||
except KeyError, e:
|
except KeyError, e:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
self.assertTrue(driver.filter_hosts(self.zone_manager, json.dumps([])))
|
self.assertTrue(hf.filter_hosts(self.zone_manager, json.dumps([])))
|
||||||
self.assertTrue(driver.filter_hosts(self.zone_manager, json.dumps({})))
|
self.assertTrue(hf.filter_hosts(self.zone_manager, json.dumps({})))
|
||||||
self.assertTrue(driver.filter_hosts(self.zone_manager, json.dumps(
|
self.assertTrue(hf.filter_hosts(self.zone_manager, json.dumps(
|
||||||
['not', True, False, True, False]
|
['not', True, False, True, False]
|
||||||
)))
|
)))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
driver.filter_hosts(self.zone_manager, json.dumps(
|
hf.filter_hosts(self.zone_manager, json.dumps(
|
||||||
'not', True, False, True, False
|
'not', True, False, True, False
|
||||||
))
|
))
|
||||||
self.fail("Should give KeyError")
|
self.fail("Should give KeyError")
|
||||||
except KeyError, e:
|
except KeyError, e:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
self.assertFalse(driver.filter_hosts(self.zone_manager, json.dumps(
|
self.assertFalse(hf.filter_hosts(self.zone_manager,
|
||||||
['=', '$foo', 100]
|
json.dumps(['=', '$foo', 100])))
|
||||||
)))
|
self.assertFalse(hf.filter_hosts(self.zone_manager,
|
||||||
self.assertFalse(driver.filter_hosts(self.zone_manager, json.dumps(
|
json.dumps(['=', '$.....', 100])))
|
||||||
['=', '$.....', 100]
|
self.assertFalse(hf.filter_hosts(self.zone_manager,
|
||||||
)))
|
json.dumps(
|
||||||
self.assertFalse(driver.filter_hosts(self.zone_manager, json.dumps(
|
['>', ['and', ['or', ['not', ['<', ['>=', ['<=', ['in', ]]]]]]]])))
|
||||||
['>', ['and', ['or', ['not', ['<', ['>=', ['<=', ['in', ]]]]]]]]
|
|
||||||
)))
|
|
||||||
|
|
||||||
self.assertFalse(driver.filter_hosts(self.zone_manager, json.dumps(
|
self.assertFalse(hf.filter_hosts(self.zone_manager,
|
||||||
['=', {}, ['>', '$missing....foo']]
|
json.dumps(['=', {}, ['>', '$missing....foo']])))
|
||||||
)))
|
|
||||||
|
|||||||
Reference in New Issue
Block a user