summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--nova/db/sqlalchemy/api.py8
-rw-r--r--nova/tests/test_db_api.py126
2 files changed, 88 insertions, 46 deletions
diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index a0f679d73..a2a373034 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -1698,16 +1698,16 @@ def instance_get_all_by_filters(context, filters, sort_key, sort_dir,
# Instances can be soft or hard deleted and the query needs to
# include or exclude both
if filters.pop('deleted'):
- if filters.pop('soft_deleted', False):
- query_prefix = query_prefix.\
- filter(models.Instance.deleted == models.Instance.id)
- else:
+ if filters.pop('soft_deleted', True):
deleted = or_(
models.Instance.deleted == models.Instance.id,
models.Instance.vm_state == vm_states.SOFT_DELETED
)
query_prefix = query_prefix.\
filter(deleted)
+ else:
+ query_prefix = query_prefix.\
+ filter(models.Instance.deleted == models.Instance.id)
else:
query_prefix = query_prefix.\
filter_by(deleted=0)
diff --git a/nova/tests/test_db_api.py b/nova/tests/test_db_api.py
index 130ed22af..0f5a2a261 100644
--- a/nova/tests/test_db_api.py
+++ b/nova/tests/test_db_api.py
@@ -30,6 +30,7 @@ from sqlalchemy.dialects import sqlite
from sqlalchemy.exc import IntegrityError
from sqlalchemy.sql.expression import select
+from nova.compute import vm_states
from nova import context
from nova import db
from nova.db.sqlalchemy import api as sqlalchemy_api
@@ -59,7 +60,7 @@ class DbTestCase(test.TestCase):
self.project_id = 'fake'
self.context = context.RequestContext(self.user_id, self.project_id)
- def create_instances_with_args(self, **kwargs):
+ def create_instance_with_args(self, **kwargs):
args = {'reservation_id': 'a', 'image_ref': 1, 'host': 'host1',
'node': 'node1', 'project_id': self.project_id,
'vm_state': 'fake'}
@@ -91,36 +92,36 @@ class DbApiTestCase(DbTestCase):
otherprojectcontext = context.RequestContext(self.user_id,
"%s2" % self.project_id)
- self.create_instances_with_args(hostname='fake_name')
+ self.create_instance_with_args(hostname='fake_name')
# With scope 'global' any duplicate should fail, be it this project:
self.flags(osapi_compute_unique_server_name_scope='global')
self.assertRaises(exception.InstanceExists,
- self.create_instances_with_args,
+ self.create_instance_with_args,
hostname='fake_name')
# or another:
self.assertRaises(exception.InstanceExists,
- self.create_instances_with_args,
+ self.create_instance_with_args,
context=otherprojectcontext,
hostname='fake_name')
# With scope 'project' a duplicate in the project should fail:
self.flags(osapi_compute_unique_server_name_scope='project')
self.assertRaises(exception.InstanceExists,
- self.create_instances_with_args,
+ self.create_instance_with_args,
hostname='fake_name')
# With scope 'project' a duplicate in a different project should work:
self.flags(osapi_compute_unique_server_name_scope='project')
- self.create_instances_with_args(context=otherprojectcontext,
- hostname='fake_name')
+ self.create_instance_with_args(context=otherprojectcontext,
+ hostname='fake_name')
self.flags(osapi_compute_unique_server_name_scope=None)
def test_instance_metadata_get_all_query(self):
- self.create_instances_with_args(metadata={'foo': 'bar'})
- self.create_instances_with_args(metadata={'baz': 'quux'})
+ self.create_instance_with_args(metadata={'foo': 'bar'})
+ self.create_instance_with_args(metadata={'baz': 'quux'})
result = db.instance_metadata_get_all(self.context, [])
self.assertEqual(2, len(result))
@@ -153,7 +154,7 @@ class DbApiTestCase(DbTestCase):
check_exc_format(db.get_instance_uuid_by_ec2_id)
def test_instance_get_all_with_meta(self):
- inst = self.create_instances_with_args()
+ inst = self.create_instance_with_args()
fake_meta, fake_sys = self.create_metadata_for_instance(inst['uuid'])
result = db.instance_get_all(self.context)
for inst in result:
@@ -163,7 +164,7 @@ class DbApiTestCase(DbTestCase):
self.assertEqual(sys_meta, fake_sys)
def test_instance_get_all_by_filters_with_meta(self):
- inst = self.create_instances_with_args()
+ inst = self.create_instance_with_args()
fake_meta, fake_sys = self.create_metadata_for_instance(inst['uuid'])
result = db.instance_get_all_by_filters(self.context, {})
for inst in result:
@@ -173,7 +174,7 @@ class DbApiTestCase(DbTestCase):
self.assertEqual(sys_meta, fake_sys)
def test_instance_get_all_by_filters_without_meta(self):
- inst = self.create_instances_with_args()
+ inst = self.create_instance_with_args()
fake_meta, fake_sys = self.create_metadata_for_instance(inst['uuid'])
result = db.instance_get_all_by_filters(self.context, {},
columns_to_join=[])
@@ -184,34 +185,41 @@ class DbApiTestCase(DbTestCase):
self.assertEqual(sys_meta, {})
def test_instance_get_all_by_filters(self):
- self.create_instances_with_args()
- self.create_instances_with_args()
+ self.create_instance_with_args()
+ self.create_instance_with_args()
result = db.instance_get_all_by_filters(self.context, {})
self.assertEqual(2, len(result))
def test_instance_get_all_by_filters_regex(self):
- self.create_instances_with_args(display_name='test1')
- self.create_instances_with_args(display_name='teeeest2')
- self.create_instances_with_args(display_name='diff')
+ self.create_instance_with_args(display_name='test1')
+ self.create_instance_with_args(display_name='teeeest2')
+ self.create_instance_with_args(display_name='diff')
result = db.instance_get_all_by_filters(self.context,
{'display_name': 't.*st.'})
self.assertEqual(2, len(result))
+ def test_instance_get_all_by_filters_exact_match(self):
+ self.create_instance_with_args(host='host1')
+ self.create_instance_with_args(host='host12')
+ result = db.instance_get_all_by_filters(self.context,
+ {'host': 'host1'})
+ self.assertEqual(1, len(result))
+
def test_instance_get_all_by_filters_metadata(self):
- self.create_instances_with_args(metadata={'foo': 'bar'})
- self.create_instances_with_args()
+ self.create_instance_with_args(metadata={'foo': 'bar'})
+ self.create_instance_with_args()
result = db.instance_get_all_by_filters(self.context,
{'metadata': {'foo': 'bar'}})
self.assertEqual(1, len(result))
def test_instance_get_all_by_filters_unicode_value(self):
- self.create_instances_with_args(display_name=u'test♥')
+ self.create_instance_with_args(display_name=u'test♥')
result = db.instance_get_all_by_filters(self.context,
{'display_name': u'test'})
self.assertEqual(1, len(result))
def test_instance_get_by_uuid(self):
- inst = self.create_instances_with_args()
+ inst = self.create_instance_with_args()
fake_meta, fake_sys = self.create_metadata_for_instance(inst['uuid'])
result = db.instance_get_by_uuid(self.context, inst['uuid'])
meta = utils.metadata_to_dict(result['metadata'])
@@ -220,7 +228,7 @@ class DbApiTestCase(DbTestCase):
self.assertEqual(sys_meta, fake_sys)
def test_instance_get_by_uuid_join_empty(self):
- inst = self.create_instances_with_args()
+ inst = self.create_instance_with_args()
fake_meta, fake_sys = self.create_metadata_for_instance(inst['uuid'])
result = db.instance_get_by_uuid(self.context, inst['uuid'],
columns_to_join=[])
@@ -230,7 +238,7 @@ class DbApiTestCase(DbTestCase):
self.assertEqual(sys_meta, {})
def test_instance_get_by_uuid_join_meta(self):
- inst = self.create_instances_with_args()
+ inst = self.create_instance_with_args()
fake_meta, fake_sys = self.create_metadata_for_instance(inst['uuid'])
result = db.instance_get_by_uuid(self.context, inst['uuid'],
columns_to_join=['metadata'])
@@ -240,7 +248,7 @@ class DbApiTestCase(DbTestCase):
self.assertEqual(sys_meta, {})
def test_instance_get_by_uuid_join_sys_meta(self):
- inst = self.create_instances_with_args()
+ inst = self.create_instance_with_args()
fake_meta, fake_sys = self.create_metadata_for_instance(inst['uuid'])
result = db.instance_get_by_uuid(self.context, inst['uuid'],
columns_to_join=['system_metadata'])
@@ -250,8 +258,8 @@ class DbApiTestCase(DbTestCase):
self.assertEqual(sys_meta, fake_sys)
def test_instance_get_all_by_filters_deleted(self):
- inst1 = self.create_instances_with_args()
- inst2 = self.create_instances_with_args(reservation_id='b')
+ inst1 = self.create_instance_with_args()
+ inst2 = self.create_instance_with_args(reservation_id='b')
db.instance_destroy(self.context, inst1['uuid'])
result = db.instance_get_all_by_filters(self.context, {})
self.assertEqual(2, len(result))
@@ -262,10 +270,44 @@ class DbApiTestCase(DbTestCase):
else:
self.assertTrue(result[1]['deleted'])
+ def test_instance_get_all_by_filters_deleted_and_soft_deleted(self):
+ inst1 = self.create_instance_with_args()
+ inst2 = self.create_instance_with_args(vm_state=vm_states.SOFT_DELETED)
+ inst3 = self.create_instance_with_args()
+ db.instance_destroy(self.context, inst1['uuid'])
+ result = db.instance_get_all_by_filters(self.context,
+ {'deleted': True})
+ self.assertEqual(2, len(result))
+ self.assertIn(inst1['id'], [result[0]['id'], result[1]['id']])
+ self.assertIn(inst2['id'], [result[0]['id'], result[1]['id']])
+
+ def test_instance_get_all_by_filters_deleted_no_soft_deleted(self):
+ inst1 = self.create_instance_with_args()
+ inst2 = self.create_instance_with_args(vm_state=vm_states.SOFT_DELETED)
+ inst3 = self.create_instance_with_args()
+ db.instance_destroy(self.context, inst1['uuid'])
+ result = db.instance_get_all_by_filters(self.context,
+ {'deleted': True,
+ 'soft_deleted': False})
+ self.assertEqual(1, len(result))
+ self.assertEqual(inst1['id'], result[0]['id'])
+
+ def test_instance_get_all_by_filters_alive_and_soft_deleted(self):
+ inst1 = self.create_instance_with_args()
+ inst2 = self.create_instance_with_args(vm_state=vm_states.SOFT_DELETED)
+ inst3 = self.create_instance_with_args()
+ db.instance_destroy(self.context, inst1['uuid'])
+ result = db.instance_get_all_by_filters(self.context,
+ {'deleted': False,
+ 'soft_deleted': True})
+ self.assertEqual(2, len(result))
+ self.assertIn(inst2['id'], [result[0]['id'], result[1]['id']])
+ self.assertIn(inst3['id'], [result[0]['id'], result[1]['id']])
+
def test_instance_get_all_by_host_and_node_no_join(self):
# Test that system metadata is not joined.
sys_meta = {'foo': 'bar'}
- expected = self.create_instances_with_args(system_metadata=sys_meta)
+ expected = self.create_instance_with_args(system_metadata=sys_meta)
elevated = self.context.elevated()
instances = db.instance_get_all_by_host_and_node(elevated, 'host1',
@@ -480,12 +522,12 @@ class DbApiTestCase(DbTestCase):
otherprojectcontext = context.RequestContext(self.user_id,
"%s2" % self.project_id)
- inst = self.create_instances_with_args(hostname='fake_name')
+ inst = self.create_instance_with_args(hostname='fake_name')
uuid1p1 = inst['uuid']
- inst = self.create_instances_with_args(hostname='fake_name2')
+ inst = self.create_instance_with_args(hostname='fake_name2')
uuid2p1 = inst['uuid']
- inst = self.create_instances_with_args(context=otherprojectcontext,
+ inst = self.create_instance_with_args(context=otherprojectcontext,
hostname='fake_name3')
uuid1p2 = inst['uuid']
@@ -1216,9 +1258,9 @@ class NotDbApiTestCase(DbTestCase):
def test_instance_get_all_by_filters_regex_unsupported_db(self):
# Ensure that the 'LIKE' operator is used for unsupported dbs.
- self.create_instances_with_args(display_name='test1')
- self.create_instances_with_args(display_name='test.*')
- self.create_instances_with_args(display_name='diff')
+ self.create_instance_with_args(display_name='test1')
+ self.create_instance_with_args(display_name='test.*')
+ self.create_instance_with_args(display_name='diff')
result = db.instance_get_all_by_filters(self.context,
{'display_name': 'test.*'})
self.assertEqual(1, len(result))
@@ -1227,9 +1269,9 @@ class NotDbApiTestCase(DbTestCase):
self.assertEqual(2, len(result))
def test_instance_get_all_by_filters_paginate(self):
- test1 = self.create_instances_with_args(display_name='test1')
- test2 = self.create_instances_with_args(display_name='test2')
- test3 = self.create_instances_with_args(display_name='test3')
+ test1 = self.create_instance_with_args(display_name='test1')
+ test2 = self.create_instance_with_args(display_name='test2')
+ test3 = self.create_instance_with_args(display_name='test3')
result = db.instance_get_all_by_filters(self.context,
{'display_name': '%test%'},
@@ -1590,17 +1632,17 @@ class SqlAlchemyDbApiTestCase(DbTestCase):
def test_instance_get_all_by_host(self):
ctxt = context.get_admin_context()
- self.create_instances_with_args()
- self.create_instances_with_args()
- self.create_instances_with_args(host='host2')
+ self.create_instance_with_args()
+ self.create_instance_with_args()
+ self.create_instance_with_args(host='host2')
result = sqlalchemy_api._instance_get_all_uuids_by_host(ctxt, 'host1')
self.assertEqual(2, len(result))
def test_instance_get_all_uuids_by_host(self):
ctxt = context.get_admin_context()
- self.create_instances_with_args()
- self.create_instances_with_args()
- self.create_instances_with_args(host='host2')
+ self.create_instance_with_args()
+ self.create_instance_with_args()
+ self.create_instance_with_args(host='host2')
result = sqlalchemy_api._instance_get_all_uuids_by_host(ctxt, 'host1')
self.assertEqual(2, len(result))
self.assertEqual(types.UnicodeType, type(result[0]))