def test_json_filter_unknown_operator_raises(self): filt_cls = filters.JsonFilter() raw = ['!=', 1, 2] filter_properties = {'query': json.dumps(raw)} capabilities = {'enabled': True, 'opt1': 'no-match'} host = fakes.FakeHostState('host1', 'compute', {'capabilities': { 'enabled': True }}) self.assertRaises(KeyError, filt_cls.host_passes, host, filter_properties)
def test_json_filter_basic_operators(self): filt_cls = filters.JsonFilter() host = fakes.FakeHostState('host1', 'compute', {'capabilities': { 'enabled': True }}) # (operator, arguments, expected_result) ops_to_test = [ ['=', [1, 1], True], ['=', [1, 2], False], ['<', [1, 2], True], ['<', [1, 1], False], ['<', [2, 1], False], ['>', [2, 1], True], ['>', [2, 2], False], ['>', [2, 3], False], ['<=', [1, 2], True], ['<=', [1, 1], True], ['<=', [2, 1], False], ['>=', [2, 1], True], ['>=', [2, 2], True], ['>=', [2, 3], False], ['in', [1, 1], True], ['in', [1, 1, 2, 3], True], ['in', [4, 1, 2, 3], False], ['not', [True], False], ['not', [False], True], ['or', [True, False], True], ['or', [False, False], False], ['and', [True, True], True], ['and', [False, False], False], ['and', [True, False], False], # Nested ((True or False) and (2 > 1)) == Passes ['and', [['or', True, False], ['>', 2, 1]], True] ] for (op, args, expected) in ops_to_test: raw = [op] + args filter_properties = {'query': json.dumps(raw)} self.assertEqual(expected, filt_cls.host_passes(host, filter_properties)) # This results in [False, True, False, True] and if any are True # then it passes... raw = ['not', True, False, True, False] filter_properties = {'query': json.dumps(raw)} self.assertTrue(filt_cls.host_passes(host, filter_properties)) # This results in [False, False, False] and if any are True # then it passes...which this doesn't raw = ['not', True, True, True] filter_properties = {'query': json.dumps(raw)} self.assertFalse(filt_cls.host_passes(host, filter_properties))
def test_json_filter_empty_filters_pass(self): filt_cls = filters.JsonFilter() capabilities = {'enabled': True, 'opt1': 'no-match'} host = fakes.FakeHostState('host1', 'compute', {'capabilities': { 'enabled': True }}) raw = [] filter_properties = {'query': json.dumps(raw)} self.assertTrue(filt_cls.host_passes(host, filter_properties)) raw = {} filter_properties = {'query': json.dumps(raw)} self.assertTrue(filt_cls.host_passes(host, filter_properties))
def test_json_filter_unknown_variable_ignored(self): filt_cls = filters.JsonFilter() capabilities = {'enabled': True, 'opt1': 'no-match'} host = fakes.FakeHostState('host1', 'compute', {'capabilities': { 'enabled': True }}) raw = ['=', '$........', 1, 1] filter_properties = {'query': json.dumps(raw)} self.assertTrue(filt_cls.host_passes(host, filter_properties)) raw = ['=', '$foo', 2, 2] filter_properties = {'query': json.dumps(raw)} self.assertTrue(filt_cls.host_passes(host, filter_properties))
def test_json_filter_passes_with_no_query(self): filt_cls = filters.JsonFilter() filter_properties = { 'instance_type': { 'memory_mb': 1024, 'root_gb': 200, 'ephemeral_gb': 0 } } capabilities = {'enabled': True} host = fakes.FakeHostState('host1', 'compute', { 'free_ram_mb': 0, 'free_disk_mb': 0, 'capabilities': capabilities }) self.assertTrue(filt_cls.host_passes(host, filter_properties))
def test_json_filter_invalid_num_arguments_fails(self): filt_cls = filters.JsonFilter() capabilities = {'enabled': True, 'opt1': 'no-match'} host = fakes.FakeHostState('host1', 'compute', {'capabilities': { 'enabled': True }}) raw = ['>', ['and', ['or', ['not', ['<', ['>=', ['<=', [ 'in', ]]]]]]]] filter_properties = {'query': json.dumps(raw)} self.assertFalse(filt_cls.host_passes(host, filter_properties)) raw = ['>', 1] filter_properties = {'query': json.dumps(raw)} self.assertFalse(filt_cls.host_passes(host, filter_properties))
def test_json_filter_fails_on_disk(self): filt_cls = filters.JsonFilter() filter_properties = { 'instance_type': { 'memory_mb': 1024, 'root_gb': 200, 'ephemeral_gb': 0 }, 'query': self.json_query } capabilities = {'enabled': True} host = fakes.FakeHostState( 'host1', 'compute', { 'free_ram_mb': 1024, 'free_disk_mb': (200 * 1024) - 1, 'capabilities': capabilities }) self.assertFalse(filt_cls.host_passes(host, filter_properties))
def test_json_filter_fails_on_service_disabled(self): filt_cls = filters.JsonFilter() json_query = json.dumps([ 'and', ['>=', '$free_ram_mb', 1024], ['>=', '$free_disk_mb', 200 * 1024], ['not', '$service.disabled'] ]) filter_properties = { 'instance_type': { 'memory_mb': 1024, 'local_gb': 200 }, 'query': json_query } capabilities = {'enabled': True} service = {'disabled': True} host = fakes.FakeHostState( 'host1', 'compute', { 'free_ram_mb': 1024, 'free_disk_mb': 200 * 1024, 'capabilities': capabilities }) self.assertFalse(filt_cls.host_passes(host, filter_properties))
def test_json_filter_happy_day(self): """Test json filter more thoroughly""" filt_cls = filters.JsonFilter() raw = [ 'and', '$capabilities.enabled', ['=', '$capabilities.opt1', 'match'], [ 'or', [ 'and', ['<', '$free_ram_mb', 30], ['<', '$free_disk_mb', 300] ], [ 'and', ['>', '$free_ram_mb', 30], ['>', '$free_disk_mb', 300] ] ] ] filter_properties = {'query': json.dumps(raw)} # Passes capabilities = {'enabled': True, 'opt1': 'match'} service = {'disabled': False} host = fakes.FakeHostState( 'host1', 'compute', { 'free_ram_mb': 10, 'free_disk_mb': 200, 'capabilities': capabilities, 'service': service }) self.assertTrue(filt_cls.host_passes(host, filter_properties)) # Passes capabilities = {'enabled': True, 'opt1': 'match'} service = {'disabled': False} host = fakes.FakeHostState( 'host1', 'compute', { 'free_ram_mb': 40, 'free_disk_mb': 400, 'capabilities': capabilities, 'service': service }) self.assertTrue(filt_cls.host_passes(host, filter_properties)) # Failes due to caps disabled capabilities = {'enabled': False, 'opt1': 'match'} service = {'disabled': False} host = fakes.FakeHostState( 'host1', 'instance_type', { 'free_ram_mb': 40, 'free_disk_mb': 400, 'capabilities': capabilities, 'service': service }) self.assertFalse(filt_cls.host_passes(host, filter_properties)) # Fails due to being exact memory/disk we don't want capabilities = {'enabled': True, 'opt1': 'match'} service = {'disabled': False} host = fakes.FakeHostState( 'host1', 'compute', { 'free_ram_mb': 30, 'free_disk_mb': 300, 'capabilities': capabilities, 'service': service }) self.assertFalse(filt_cls.host_passes(host, filter_properties)) # Fails due to memory lower but disk higher capabilities = {'enabled': True, 'opt1': 'match'} service = {'disabled': False} host = fakes.FakeHostState( 'host1', 'compute', { 'free_ram_mb': 20, 'free_disk_mb': 400, 'capabilities': capabilities, 'service': service }) self.assertFalse(filt_cls.host_passes(host, filter_properties)) # Fails due to capabilities 'opt1' not equal capabilities = {'enabled': True, 'opt1': 'no-match'} service = {'enabled': True} host = fakes.FakeHostState( 'host1', 'compute', { 'free_ram_mb': 20, 'free_disk_mb': 400, 'capabilities': capabilities, 'service': service }) self.assertFalse(filt_cls.host_passes(host, filter_properties))
def test_json_filter(self): hf = filters.JsonFilter() # filter all hosts that can support 50 ram and 500 disk name, cooked = hf.instance_type_to_filter(self.instance_type) self.assertEquals(name.split(".")[-1], 'JsonFilter') hosts = hf.filter_hosts(self.zone_manager, cooked) self.assertEquals(6, len(hosts)) just_hosts = [host for host, caps in hosts] just_hosts.sort() self.assertEquals('host05', just_hosts[0]) self.assertEquals('host10', just_hosts[5]) # Try some custom queries raw = ['or', ['and', ['<', '$compute.host_memory_free', 30], ['<', '$compute.disk_available', 300], ], ['and', ['>', '$compute.host_memory_free', 70], ['>', '$compute.disk_available', 700], ] ] cooked = json.dumps(raw) hosts = hf.filter_hosts(self.zone_manager, cooked) self.assertEquals(5, len(hosts)) just_hosts = [host for host, caps in hosts] just_hosts.sort() for index, host in zip([1, 2, 8, 9, 10], just_hosts): self.assertEquals('host%02d' % index, host) raw = ['not', ['=', '$compute.host_memory_free', 30], ] cooked = json.dumps(raw) hosts = hf.filter_hosts(self.zone_manager, cooked) self.assertEquals(9, len(hosts)) just_hosts = [host for host, caps in hosts] just_hosts.sort() for index, host in zip([1, 2, 4, 5, 6, 7, 8, 9, 10], just_hosts): self.assertEquals('host%02d' % index, host) raw = ['in', '$compute.host_memory_free', 20, 40, 60, 80, 100] cooked = json.dumps(raw) hosts = hf.filter_hosts(self.zone_manager, cooked) self.assertEquals(5, len(hosts)) just_hosts = [host for host, caps in hosts] just_hosts.sort() for index, host in zip([2, 4, 6, 8, 10], just_hosts): self.assertEquals('host%02d' % index, host) # Try some bogus input ... raw = ['unknown command', ] cooked = json.dumps(raw) try: hf.filter_hosts(self.zone_manager, cooked) self.fail("Should give KeyError") except KeyError, e: pass