From a3096d593fbe21625e3c4102e69d12950e9d2ef2 Mon Sep 17 00:00:00 2001 From: Chris Behrens Date: Tue, 12 Jul 2011 02:01:09 -0700 Subject: added searching by instance name added unit tests --- nova/compute/api.py | 5 + nova/db/api.py | 7 ++ nova/db/sqlalchemy/api.py | 24 +++- nova/tests/test_compute.py | 265 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 300 insertions(+), 1 deletion(-) (limited to 'nova') diff --git a/nova/compute/api.py b/nova/compute/api.py index fba56a2bb..605b0d29c 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -641,6 +641,10 @@ class API(base.Base): raise exception.FixedIpNotFoundForAddress(address=fixed_ip) return instances + def _get_all_by_name(self, context, search_opts): + return self.db.instance_get_all_by_name_regexp( + context, search_opts['name']) + def _get_all_by_ip(self, context, search_opts): return self.db.instance_get_all_by_ip_regexp( context, search_opts['ip']) @@ -673,6 +677,7 @@ class API(base.Base): exclusive_opts = ['reservation_id', 'project_id', 'fixed_ip', + 'name', 'ip', 'ip6'] + search_columns diff --git a/nova/db/api.py b/nova/db/api.py index c0f49d98d..6aa44f06b 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -529,6 +529,13 @@ def instance_get_all_by_column_regexp(context, column, column_regexp): column_regexp) +def instance_get_all_by_name_regexp(context, name_regexp): + """Get all instances by using regular expression matching against + its name + """ + return IMPL.instance_get_all_by_name_regexp(context, name_regexp) + + def instance_get_all_by_ip_regexp(context, ip_regexp): """Get all instances by using regular expression matching against Floating and Fixed IP Addresses diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 99e96e679..93614a307 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -1262,6 +1262,28 @@ def instance_get_all_by_column_regexp(context, column, column_regexp): return instances +@require_context +def instance_get_all_by_name_regexp(context, ipv6_regexp): + """Get all instances by using regular expression matching against + its name + """ + + session = get_session() + with session.begin(): + # get instances + + all_instances = session.query(models.Instance).\ + options(joinedload('metadata')).\ + filter_by(deleted=can_read_deleted(context)).\ + all() + if not all_instances: + return [] + + compiled_regexp = re.compile(ipv6_regexp) + return [instance for instance in all_instances + if compiled_regexp.match(instance.name)] + + @require_context def instance_get_all_by_ip_regexp(context, ip_regexp): """Get all instances by using regular expression matching against @@ -1319,7 +1341,7 @@ def instance_get_all_by_ip_regexp(context, ip_regexp): @require_context -def instance_get_all_by_ipv6_regex(context, ipv6_regexp): +def instance_get_all_by_ipv6_regexp(context, ipv6_regexp): """Get all instances by using regular expression matching against IPv6 Addresses """ diff --git a/nova/tests/test_compute.py b/nova/tests/test_compute.py index 45cd2f764..0190a5f73 100644 --- a/nova/tests/test_compute.py +++ b/nova/tests/test_compute.py @@ -30,6 +30,7 @@ from nova.compute import power_state from nova import context from nova import db from nova.db.sqlalchemy import models +from nova.db.sqlalchemy import api as sqlalchemy_api from nova import exception from nova import flags import nova.image.fake @@ -810,3 +811,267 @@ class ComputeTestCase(test.TestCase): LOG.info(_("After force-killing instances: %s"), instances) self.assertEqual(len(instances), 1) self.assertEqual(power_state.SHUTOFF, instances[0]['state']) + + def test_get_all_by_display_name_regexp(self): + """Test searching instances by display_name""" + c = context.get_admin_context() + instance_id1 = self._create_instance({'display_name': 'woot'}) + instance_id2 = self._create_instance({ + 'display_name': 'woo', + 'id': 20}) + instance_id3 = self._create_instance({ + 'display_name': 'not-woot', + 'id': 30}) + + instances = self.compute_api.get_all(c, + search_opts={'display_name': 'woo.*'}) + self.assertEqual(len(instances), 2) + instance_ids = [instance.id for instance in instances] + self.assertTrue(instance_id1 in instance_ids) + self.assertTrue(instance_id2 in instance_ids) + + instances = self.compute_api.get_all(c, + search_opts={'display_name': 'woot.*'}) + instance_ids = [instance.id for instance in instances] + self.assertEqual(len(instances), 1) + self.assertTrue(instance_id1 in instance_ids) + + instances = self.compute_api.get_all(c, + search_opts={'display_name': '.*oot.*'}) + self.assertEqual(len(instances), 2) + instance_ids = [instance.id for instance in instances] + self.assertTrue(instance_id1 in instance_ids) + self.assertTrue(instance_id3 in instance_ids) + + instances = self.compute_api.get_all(c, + search_opts={'display_name': 'n.*'}) + self.assertEqual(len(instances), 1) + instance_ids = [instance.id for instance in instances] + self.assertTrue(instance_id3 in instance_ids) + + instances = self.compute_api.get_all(c, + search_opts={'display_name': 'noth.*'}) + self.assertEqual(len(instances), 0) + + db.instance_destroy(c, instance_id1) + db.instance_destroy(c, instance_id2) + db.instance_destroy(c, instance_id3) + + def test_get_all_by_server_name_regexp(self): + """Test searching instances by server_name""" + c = context.get_admin_context() + instance_id1 = self._create_instance({'server_name': 'woot'}) + instance_id2 = self._create_instance({ + 'server_name': 'woo', + 'id': 20}) + instance_id3 = self._create_instance({ + 'server_name': 'not-woot', + 'id': 30}) + + instances = self.compute_api.get_all(c, + search_opts={'server_name': 'woo.*'}) + self.assertEqual(len(instances), 2) + instance_ids = [instance.id for instance in instances] + self.assertTrue(instance_id1 in instance_ids) + self.assertTrue(instance_id2 in instance_ids) + + instances = self.compute_api.get_all(c, + search_opts={'server_name': 'woot.*'}) + instance_ids = [instance.id for instance in instances] + self.assertEqual(len(instances), 1) + self.assertTrue(instance_id1 in instance_ids) + + instances = self.compute_api.get_all(c, + search_opts={'server_name': '.*oot.*'}) + self.assertEqual(len(instances), 2) + instance_ids = [instance.id for instance in instances] + self.assertTrue(instance_id1 in instance_ids) + self.assertTrue(instance_id3 in instance_ids) + + instances = self.compute_api.get_all(c, + search_opts={'server_name': 'n.*'}) + self.assertEqual(len(instances), 1) + instance_ids = [instance.id for instance in instances] + self.assertTrue(instance_id3 in instance_ids) + + instances = self.compute_api.get_all(c, + search_opts={'server_name': 'noth.*'}) + self.assertEqual(len(instances), 0) + + db.instance_destroy(c, instance_id1) + db.instance_destroy(c, instance_id2) + db.instance_destroy(c, instance_id3) + + def test_get_all_by_name_regexp(self): + """Test searching instances by name""" + self.flags(instance_name_template='instance-%d') + + c = context.get_admin_context() + instance_id1 = self._create_instance() + instance_id2 = self._create_instance({'id': 2}) + instance_id3 = self._create_instance({'id': 10}) + + instances = self.compute_api.get_all(c, + search_opts={'name': 'instance.*'}) + self.assertEqual(len(instances), 3) + + instances = self.compute_api.get_all(c, + search_opts={'name': '.*\-\d$'}) + self.assertEqual(len(instances), 2) + instance_ids = [instance.id for instance in instances] + self.assertTrue(instance_id1 in instance_ids) + self.assertTrue(instance_id2 in instance_ids) + + instances = self.compute_api.get_all(c, + search_opts={'name': 'i.*2'}) + self.assertEqual(len(instances), 1) + self.assertEqual(instances[0].id, instance_id2) + + db.instance_destroy(c, instance_id1) + db.instance_destroy(c, instance_id2) + db.instance_destroy(c, instance_id3) + + def test_get_by_fixed_ip(self): + """Test getting 1 instance by Fixed IP""" + c = context.get_admin_context() + instance_id1 = self._create_instance({'server_name': 'woot'}) + instance_id2 = self._create_instance({ + 'server_name': 'woo', + 'id': 20}) + instance_id3 = self._create_instance({ + 'server_name': 'not-woot', + 'id': 30}) + + db.fixed_ip_create(c, + {'address': '1.1.1.1', + 'instance_id': instance_id1}) + db.fixed_ip_create(c, + {'address': '1.1.2.1', + 'instance_id': instance_id2}) + + # regex not allowed + self.assertRaises(exception.NotFound, + self.compute_api.get_all, + c, + search_opts={'fixed_ip': '.*'}) + + self.assertRaises(exception.NotFound, + self.compute_api.get_all, + c, + search_opts={'fixed_ip': '1.1.3.1'}) + + instances = self.compute_api.get_all(c, + search_opts={'fixed_ip': '1.1.1.1'}) + self.assertEqual(len(instances), 1) + self.assertEqual(instances[0].id, instance_id1) + + instances = self.compute_api.get_all(c, + search_opts={'fixed_ip': '1.1.2.1'}) + self.assertEqual(len(instances), 1) + self.assertEqual(instances[0].id, instance_id2) + + db.instance_destroy(c, instance_id1) + db.instance_destroy(c, instance_id2) + + def test_get_all_by_ip_regex(self): + """Test searching by Floating and Fixed IP""" + c = context.get_admin_context() + instance_id1 = self._create_instance({'server_name': 'woot'}) + instance_id2 = self._create_instance({ + 'server_name': 'woo', + 'id': 20}) + instance_id3 = self._create_instance({ + 'server_name': 'not-woot', + 'id': 30}) + + db.fixed_ip_create(c, + {'address': '1.1.1.1', + 'instance_id': instance_id1}) + db.fixed_ip_create(c, + {'address': '1.1.2.1', + 'instance_id': instance_id2}) + fix_addr = db.fixed_ip_create(c, + {'address': '1.1.3.1', + 'instance_id': instance_id3}) + fix_ref = db.fixed_ip_get_by_address(c, fix_addr) + flo_ref = db.floating_ip_create(c, + {'address': '10.0.0.2', + 'fixed_ip_id': fix_ref['id']}) + + instances = self.compute_api.get_all(c, + search_opts={'ip': '.*\.1'}) + self.assertEqual(len(instances), 3) + + instances = self.compute_api.get_all(c, + search_opts={'ip': '1.*'}) + self.assertEqual(len(instances), 3) + + instances = self.compute_api.get_all(c, + search_opts={'ip': '.*\.1.\d+$'}) + self.assertEqual(len(instances), 1) + instance_ids = [instance.id for instance in instances] + self.assertTrue(instance_id1 in instance_ids) + + instances = self.compute_api.get_all(c, + search_opts={'ip': '.*\.2.+'}) + self.assertEqual(len(instances), 1) + instance_ids = [instance.id for instance in instances] + self.assertTrue(instance_id2 in instance_ids) + + instances = self.compute_api.get_all(c, + search_opts={'ip': '10.*'}) + self.assertEqual(len(instances), 1) + instance_ids = [instance.id for instance in instances] + self.assertTrue(instance_id3 in instance_ids) + + db.instance_destroy(c, instance_id1) + db.instance_destroy(c, instance_id2) + db.instance_destroy(c, instance_id3) + db.floating_ip_destroy(c, '10.0.0.2') + + def test_get_all_by_ipv6_regex(self): + """Test searching by IPv6 address""" + def fake_ipv6_get_by_instance_ref(context, instance): + if instance.id == 1: + return ['ffff:ffff::1'] + if instance.id == 20: + return ['dddd:dddd::1'] + if instance.id == 30: + return ['cccc:cccc::1', 'eeee:eeee::1', 'dddd:dddd::1'] + + self.stubs.Set(sqlalchemy_api, '_ipv6_get_by_instance_ref', + fake_ipv6_get_by_instance_ref) + + c = context.get_admin_context() + instance_id1 = self._create_instance({'server_name': 'woot'}) + instance_id2 = self._create_instance({ + 'server_name': 'woo', + 'id': 20}) + instance_id3 = self._create_instance({ + 'server_name': 'not-woot', + 'id': 30}) + + instances = self.compute_api.get_all(c, + search_opts={'ip6': 'ff.*'}) + self.assertEqual(len(instances), 1) + instance_ids = [instance.id for instance in instances] + self.assertTrue(instance_id1 in instance_ids) + + instances = self.compute_api.get_all(c, + search_opts={'ip6': '.*::1'}) + self.assertEqual(len(instances), 3) + instance_ids = [instance.id for instance in instances] + self.assertTrue(instance_id1 in instance_ids) + self.assertTrue(instance_id2 in instance_ids) + self.assertTrue(instance_id3 in instance_ids) + + instances = self.compute_api.get_all(c, + search_opts={'ip6': '.*dd:.*'}) + self.assertEqual(len(instances), 2) + instance_ids = [instance.id for instance in instances] + self.assertTrue(instance_id2 in instance_ids) + self.assertTrue(instance_id3 in instance_ids) + + db.instance_destroy(c, instance_id1) + db.instance_destroy(c, instance_id2) + db.instance_destroy(c, instance_id3) -- cgit