diff options
Diffstat (limited to 'nova/tests/db/test_db_api.py')
-rw-r--r-- | nova/tests/db/test_db_api.py | 1027 |
1 files changed, 525 insertions, 502 deletions
diff --git a/nova/tests/db/test_db_api.py b/nova/tests/db/test_db_api.py index 7ba431695..15ef5c3c1 100644 --- a/nova/tests/db/test_db_api.py +++ b/nova/tests/db/test_db_api.py @@ -121,215 +121,20 @@ class DbTestCase(test.TestCase): class DbApiTestCase(DbTestCase): - def test_create_instance_unique_hostname(self): - otherprojectcontext = context.RequestContext(self.user_id, - "%s2" % self.project_id) - - 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_instance_with_args, - hostname='fake_name') - - # or another: - self.assertRaises(exception.InstanceExists, - 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_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_instance_with_args(context=otherprojectcontext, - hostname='fake_name') - - self.flags(osapi_compute_unique_server_name_scope=None) def test_ec2_ids_not_found_are_printable(self): - def check_exc_format(method): + def check_exc_format(method, value): try: - method(self.context, 'fake') + method(self.context, value) except exception.NotFound as exc: - self.assertTrue('fake' in unicode(exc)) - - check_exc_format(db.get_ec2_volume_id_by_uuid) - check_exc_format(db.get_volume_uuid_by_ec2_id) - check_exc_format(db.get_ec2_snapshot_id_by_uuid) - check_exc_format(db.get_snapshot_uuid_by_ec2_id) - check_exc_format(db.get_ec2_instance_id_by_uuid) - check_exc_format(db.get_instance_uuid_by_ec2_id) - - def test_instance_get_all_with_meta(self): - 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: - meta = utils.metadata_to_dict(inst['metadata']) - self.assertEqual(meta, fake_meta) - sys_meta = utils.metadata_to_dict(inst['system_metadata']) - self.assertEqual(sys_meta, fake_sys) - - def test_instance_get_all_by_filters_with_meta(self): - 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: - meta = utils.metadata_to_dict(inst['metadata']) - self.assertEqual(meta, fake_meta) - sys_meta = utils.metadata_to_dict(inst['system_metadata']) - self.assertEqual(sys_meta, fake_sys) - - def test_instance_get_all_by_filters_without_meta(self): - 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=[]) - for inst in result: - meta = utils.metadata_to_dict(inst['metadata']) - self.assertEqual(meta, {}) - sys_meta = utils.metadata_to_dict(inst['system_metadata']) - self.assertEqual(sys_meta, {}) - - def test_instance_get_all_by_filters(self): - 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_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_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_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_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']) - self.assertEqual(meta, fake_meta) - sys_meta = utils.metadata_to_dict(result['system_metadata']) - self.assertEqual(sys_meta, fake_sys) - - def test_instance_get_by_uuid_join_empty(self): - 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=[]) - meta = utils.metadata_to_dict(result['metadata']) - self.assertEqual(meta, {}) - sys_meta = utils.metadata_to_dict(result['system_metadata']) - self.assertEqual(sys_meta, {}) - - def test_instance_get_by_uuid_join_meta(self): - 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']) - meta = utils.metadata_to_dict(result['metadata']) - self.assertEqual(meta, fake_meta) - sys_meta = utils.metadata_to_dict(result['system_metadata']) - self.assertEqual(sys_meta, {}) - - def test_instance_get_by_uuid_join_sys_meta(self): - 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']) - meta = utils.metadata_to_dict(result['metadata']) - self.assertEqual(meta, {}) - sys_meta = utils.metadata_to_dict(result['system_metadata']) - self.assertEqual(sys_meta, fake_sys) - - def test_instance_get_all_by_filters_deleted(self): - 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)) - self.assertIn(inst1['id'], [result[0]['id'], result[1]['id']]) - self.assertIn(inst2['id'], [result[0]['id'], result[1]['id']]) - if inst1['id'] == result[0]['id']: - self.assertTrue(result[0]['deleted']) - else: - self.assertTrue(result[1]['deleted']) + self.assertTrue(unicode(value) in unicode(exc)) - 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_instance_with_args(system_metadata=sys_meta) - - elevated = self.context.elevated() - instances = db.instance_get_all_by_host_and_node(elevated, 'host1', - 'node1') - self.assertEqual(1, len(instances)) - instance = instances[0] - self.assertEqual(expected['uuid'], instance['uuid']) - sysmeta = dict(instance)['system_metadata'] - self.assertEqual(len(sysmeta), 0) + check_exc_format(db.get_ec2_volume_id_by_uuid, 'fake') + check_exc_format(db.get_volume_uuid_by_ec2_id, 123456) + check_exc_format(db.get_ec2_snapshot_id_by_uuid, 'fake') + check_exc_format(db.get_snapshot_uuid_by_ec2_id, 123456) + check_exc_format(db.get_ec2_instance_id_by_uuid, 'fake') + check_exc_format(db.get_instance_uuid_by_ec2_id, 123456) def test_migration_get_unconfirmed_by_dest_compute(self): ctxt = context.get_admin_context() @@ -370,206 +175,6 @@ class DbApiTestCase(DbTestCase): self.assertEqual(0, len(results)) db.migration_update(ctxt, migration['id'], {"status": "CONFIRMED"}) - def test_instance_get_all_hung_in_rebooting(self): - ctxt = context.get_admin_context() - - # Ensure no instances are returned. - results = db.instance_get_all_hung_in_rebooting(ctxt, 10) - self.assertEqual(0, len(results)) - - # Ensure one rebooting instance with updated_at older than 10 seconds - # is returned. - updated_at = datetime.datetime(2000, 1, 1, 12, 0, 0) - values = {"task_state": "rebooting", "updated_at": updated_at} - instance = db.instance_create(ctxt, values) - results = db.instance_get_all_hung_in_rebooting(ctxt, 10) - self.assertEqual(1, len(results)) - db.instance_update(ctxt, instance['uuid'], {"task_state": None}) - - # Ensure the newly rebooted instance is not returned. - updated_at = timeutils.utcnow() - values = {"task_state": "rebooting", "updated_at": updated_at} - instance = db.instance_create(ctxt, values) - results = db.instance_get_all_hung_in_rebooting(ctxt, 10) - self.assertEqual(0, len(results)) - db.instance_update(ctxt, instance['uuid'], {"task_state": None}) - - def test_instance_update_with_expected_vm_state(self): - ctxt = context.get_admin_context() - uuid = uuidutils.generate_uuid() - updates = {'expected_vm_state': 'meow', - 'moo': 'cow'} - - class FakeInstance(dict): - def save(self, session=None): - pass - - fake_instance_values = {'vm_state': 'meow', - 'hostname': '', - 'metadata': None, - 'system_metadata': None} - fake_instance = FakeInstance(fake_instance_values) - - self.mox.StubOutWithMock(sqlalchemy_api, '_instance_get_by_uuid') - self.mox.StubOutWithMock(fake_instance, 'save') - - sqlalchemy_api._instance_get_by_uuid(ctxt, uuid, - session=mox.IgnoreArg()).AndReturn(fake_instance) - fake_instance.save(session=mox.IgnoreArg()) - - self.mox.ReplayAll() - - result = db.instance_update(ctxt, uuid, updates) - expected_instance = dict(fake_instance_values) - expected_instance['moo'] = 'cow' - self.assertEqual(expected_instance, result) - - def test_instance_update_with_unexpected_vm_state(self): - ctxt = context.get_admin_context() - uuid = uuidutils.generate_uuid() - updates = {'expected_vm_state': 'meow'} - fake_instance = {'vm_state': 'nomatch'} - - self.mox.StubOutWithMock(sqlalchemy_api, '_instance_get_by_uuid') - - sqlalchemy_api._instance_get_by_uuid(ctxt, uuid, - session=mox.IgnoreArg()).AndReturn(fake_instance) - - self.mox.ReplayAll() - - self.assertRaises(exception.UnexpectedVMStateError, - db.instance_update, ctxt, uuid, updates) - - def test_instance_update_with_instance_uuid(self): - # test instance_update() works when an instance UUID is passed. - ctxt = context.get_admin_context() - - # Create an instance with some metadata - values = {'metadata': {'host': 'foo', 'key1': 'meow'}, - 'system_metadata': {'original_image_ref': 'blah'}} - instance = db.instance_create(ctxt, values) - - # Update the metadata - values = {'metadata': {'host': 'bar', 'key2': 'wuff'}, - 'system_metadata': {'original_image_ref': 'baz'}} - db.instance_update(ctxt, instance['uuid'], values) - - # Retrieve the user-provided metadata to ensure it was successfully - # updated - instance_meta = db.instance_metadata_get(ctxt, instance['uuid']) - self.assertEqual('bar', instance_meta['host']) - self.assertEqual('wuff', instance_meta['key2']) - self.assertNotIn('key1', instance_meta) - - # Retrieve the system metadata to ensure it was successfully updated - system_meta = db.instance_system_metadata_get(ctxt, instance['uuid']) - self.assertEqual('baz', system_meta['original_image_ref']) - - def test_delete_instance_metadata_on_instance_destroy(self): - ctxt = context.get_admin_context() - - # Create an instance with some metadata - values = {'metadata': {'host': 'foo', 'key1': 'meow'}, - 'system_metadata': {'original_image_ref': 'blah'}} - instance = db.instance_create(ctxt, values) - instance_meta = db.instance_metadata_get(ctxt, instance['uuid']) - self.assertEqual('foo', instance_meta['host']) - self.assertEqual('meow', instance_meta['key1']) - db.instance_destroy(ctxt, instance['uuid']) - instance_meta = db.instance_metadata_get(ctxt, instance['uuid']) - # Make sure instance metadata is deleted as well - self.assertEqual({}, instance_meta) - - def test_instance_update_unique_name(self): - otherprojectcontext = context.RequestContext(self.user_id, - "%s2" % self.project_id) - - inst = self.create_instance_with_args(hostname='fake_name') - uuid1p1 = inst['uuid'] - inst = self.create_instance_with_args(hostname='fake_name2') - uuid2p1 = inst['uuid'] - - inst = self.create_instance_with_args(context=otherprojectcontext, - hostname='fake_name3') - uuid1p2 = inst['uuid'] - - # osapi_compute_unique_server_name_scope is unset so this should work: - values = {'hostname': 'fake_name2'} - db.instance_update(self.context, uuid1p1, values) - values = {'hostname': 'fake_name'} - db.instance_update(self.context, uuid1p1, values) - - # With scope 'global' any duplicate should fail. - self.flags(osapi_compute_unique_server_name_scope='global') - self.assertRaises(exception.InstanceExists, - db.instance_update, - self.context, - uuid2p1, - values) - - self.assertRaises(exception.InstanceExists, - db.instance_update, - otherprojectcontext, - uuid1p2, - values) - - # But we should definitely be able to update our name if we aren't - # really changing it. - case_only_values = {'hostname': 'fake_NAME'} - db.instance_update(self.context, uuid1p1, case_only_values) - - # With scope 'project' a duplicate in the project should fail: - self.flags(osapi_compute_unique_server_name_scope='project') - self.assertRaises(exception.InstanceExists, - db.instance_update, - self.context, - uuid2p1, - values) - - # With scope 'project' a duplicate in a different project should work: - self.flags(osapi_compute_unique_server_name_scope='project') - db.instance_update(otherprojectcontext, uuid1p2, values) - - def test_instance_update_with_and_get_original(self): - ctxt = context.get_admin_context() - - # Create an instance with some metadata - values = {'vm_state': 'building'} - instance = db.instance_create(ctxt, values) - - (old_ref, new_ref) = db.instance_update_and_get_original(ctxt, - instance['uuid'], {'vm_state': 'needscoffee'}) - self.assertEquals("building", old_ref["vm_state"]) - self.assertEquals("needscoffee", new_ref["vm_state"]) - - def _test_instance_update_updates_metadata(self, metadata_type): - ctxt = context.get_admin_context() - - instance = db.instance_create(ctxt, {}) - - def set_and_check(meta): - inst = db.instance_update(ctxt, instance['uuid'], - {metadata_type: dict(meta)}) - _meta = utils.metadata_to_dict(inst[metadata_type]) - self.assertEqual(meta, _meta) - - meta = {'speed': '88', 'units': 'MPH'} - set_and_check(meta) - - meta['gigawatts'] = '1.21' - set_and_check(meta) - - del meta['gigawatts'] - set_and_check(meta) - - def test_instance_update_updates_system_metadata(self): - # Ensure that system_metadata is updated during instance_update - self._test_instance_update_updates_metadata('system_metadata') - - def test_instance_update_updates_metadata(self): - # Ensure that metadata is updated during instance_update - self._test_instance_update_updates_metadata('metadata') - def test_add_key_pair(self, name=None): """Check if keypair creation work as expected.""" keypair = { @@ -643,34 +248,6 @@ class DbApiTestCase(DbTestCase): db.dnsdomain_unregister(ctxt, domain1) db.dnsdomain_unregister(ctxt, domain2) - def test_instance_floating_address_get_all(self): - ctxt = context.get_admin_context() - - instance1 = db.instance_create(ctxt, {'host': 'h1', 'hostname': 'n1'}) - instance2 = db.instance_create(ctxt, {'host': 'h2', 'hostname': 'n2'}) - - fixed_addresses = ['1.1.1.1', '1.1.1.2', '1.1.1.3'] - float_addresses = ['2.1.1.1', '2.1.1.2', '2.1.1.3'] - instance_uuids = [instance1['uuid'], instance1['uuid'], - instance2['uuid']] - - for fixed_addr, float_addr, instance_uuid in zip(fixed_addresses, - float_addresses, - instance_uuids): - db.fixed_ip_create(ctxt, {'address': fixed_addr, - 'instance_uuid': instance_uuid}) - fixed_id = db.fixed_ip_get_by_address(ctxt, fixed_addr)['id'] - db.floating_ip_create(ctxt, - {'address': float_addr, - 'fixed_ip_id': fixed_id}) - - real_float_addresses = \ - db.instance_floating_address_get_all(ctxt, instance_uuids[0]) - self.assertEqual(set(float_addresses[:2]), set(real_float_addresses)) - real_float_addresses = \ - db.instance_floating_address_get_all(ctxt, instance_uuids[2]) - self.assertEqual(set([float_addresses[2]]), set(real_float_addresses)) - def test_get_vol_mapping_non_admin(self): ref = db.ec2_volume_create(self.context, 'fake-uuid') ec2_id = db.get_ec2_volume_id_by_uuid(self.context, 'fake-uuid') @@ -948,8 +525,8 @@ class AggregateDBApiTestCase(test.TestCase): values2 = {'name': 'fake_aggregate4'} a1 = _create_aggregate_with_hosts(context=ctxt, metadata={'goodkey': 'good'}) - a2 = _create_aggregate_with_hosts(context=ctxt, values=values) - a3 = _create_aggregate(context=ctxt, values=values2) + _create_aggregate_with_hosts(context=ctxt, values=values) + _create_aggregate(context=ctxt, values=values2) # filter result by key r1 = db.aggregate_get_by_host(ctxt, 'foo.openstack.org', key='goodkey') self.assertEqual([a1['id']], [x['id'] for x in r1]) @@ -958,9 +535,9 @@ class AggregateDBApiTestCase(test.TestCase): ctxt = context.get_admin_context() values = {'name': 'fake_aggregate2'} values2 = {'name': 'fake_aggregate3'} - a1 = _create_aggregate_with_hosts(context=ctxt) - a2 = _create_aggregate_with_hosts(context=ctxt, values=values) - a3 = _create_aggregate_with_hosts(context=ctxt, values=values2, + _create_aggregate_with_hosts(context=ctxt) + _create_aggregate_with_hosts(context=ctxt, values=values) + _create_aggregate_with_hosts(context=ctxt, values=values2, hosts=['bar.openstack.org'], metadata={'badkey': 'bad'}) r1 = db.aggregate_metadata_get_by_host(ctxt, 'foo.openstack.org') self.assertEqual(r1['fake_key1'], set(['fake_value1'])) @@ -970,8 +547,8 @@ class AggregateDBApiTestCase(test.TestCase): ctxt = context.get_admin_context() values = {'name': 'fake_aggregate2'} values2 = {'name': 'fake_aggregate3'} - a1 = _create_aggregate_with_hosts(context=ctxt) - a2 = _create_aggregate_with_hosts(context=ctxt, values=values) + _create_aggregate_with_hosts(context=ctxt) + _create_aggregate_with_hosts(context=ctxt, values=values) a3 = _create_aggregate_with_hosts(context=ctxt, values=values2, hosts=['foo.openstack.org'], metadata={'good': 'value'}) r1 = db.aggregate_metadata_get_by_host(ctxt, 'foo.openstack.org', @@ -988,9 +565,9 @@ class AggregateDBApiTestCase(test.TestCase): ctxt = context.get_admin_context() values = {'name': 'fake_aggregate2'} values2 = {'name': 'fake_aggregate3'} - a1 = _create_aggregate_with_hosts(context=ctxt) - a2 = _create_aggregate_with_hosts(context=ctxt, values=values) - a3 = _create_aggregate_with_hosts(context=ctxt, values=values2, + _create_aggregate_with_hosts(context=ctxt) + _create_aggregate_with_hosts(context=ctxt, values=values) + _create_aggregate_with_hosts(context=ctxt, values=values2, hosts=['foo.openstack.org'], metadata={'good': 'value'}) r1 = db.aggregate_host_get_by_metadata_key(ctxt, key='good') self.assertEqual(r1, {'foo.openstack.org': set(['value'])}) @@ -1464,7 +1041,7 @@ class ReservationTestCase(test.TestCase, ModelsObjectComparatorMixin): def test_reservation_expire(self): self.values['expire'] = datetime.datetime.utcnow() + datetime.\ timedelta(days=1) - reservations = self._quota_reserve() + self._quota_reserve() db.reservation_expire(self.ctxt) expected = {'project_id': 'project1', @@ -1628,8 +1205,7 @@ class SecurityGroupTestCase(test.TestCase, ModelsObjectComparatorMixin): def test_security_group_get(self): security_group1 = self._create_security_group({}) - security_group2 = self._create_security_group( - {'name': 'fake_sec_group2'}) + self._create_security_group({'name': 'fake_sec_group2'}) real_security_group = db.security_group_get(self.ctxt, security_group1['id'], columns_to_join=['instances']) @@ -1742,8 +1318,8 @@ class SecurityGroupTestCase(test.TestCase, ModelsObjectComparatorMixin): {'name': 'fake2', 'project_id': 'fake_proj1'}, {'name': 'fake3', 'project_id': 'fake_proj2'}, ] - security_groups = [self._create_security_group(vals) - for vals in values] + for vals in values: + self._create_security_group(vals) real = [] for project in ('fake_proj1', 'fake_proj2'): @@ -1776,13 +1352,445 @@ class SecurityGroupTestCase(test.TestCase, ModelsObjectComparatorMixin): self.ctxt.project_id, 'default')) - default_group = db.security_group_ensure_default(self.ctxt) + db.security_group_ensure_default(self.ctxt) self.assertTrue(db.security_group_exists(self.ctxt, self.ctxt.project_id, 'default')) +class InstanceTestCase(DbTestCase): + + """Tests for db.api.instance_* methods.""" + + def setUp(self): + super(InstanceTestCase, self).setUp() + + def test_create_instance_unique_hostname(self): + otherprojectcontext = context.RequestContext(self.user_id, + "%s2" % self.project_id) + + 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_instance_with_args, + hostname='fake_name') + + # or another: + self.assertRaises(exception.InstanceExists, + 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_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_instance_with_args(context=otherprojectcontext, + hostname='fake_name') + + self.flags(osapi_compute_unique_server_name_scope=None) + + def test_instance_get_all_with_meta(self): + 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: + meta = utils.metadata_to_dict(inst['metadata']) + self.assertEqual(meta, fake_meta) + sys_meta = utils.metadata_to_dict(inst['system_metadata']) + self.assertEqual(sys_meta, fake_sys) + + def test_instance_get_all_by_filters_with_meta(self): + 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: + meta = utils.metadata_to_dict(inst['metadata']) + self.assertEqual(meta, fake_meta) + sys_meta = utils.metadata_to_dict(inst['system_metadata']) + self.assertEqual(sys_meta, fake_sys) + + def test_instance_get_all_by_filters_without_meta(self): + 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=[]) + for inst in result: + meta = utils.metadata_to_dict(inst['metadata']) + self.assertEqual(meta, {}) + sys_meta = utils.metadata_to_dict(inst['system_metadata']) + self.assertEqual(sys_meta, {}) + + def test_instance_get_all_by_filters(self): + 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_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_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_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_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']) + self.assertEqual(meta, fake_meta) + sys_meta = utils.metadata_to_dict(result['system_metadata']) + self.assertEqual(sys_meta, fake_sys) + + def test_instance_get_by_uuid_join_empty(self): + 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=[]) + meta = utils.metadata_to_dict(result['metadata']) + self.assertEqual(meta, {}) + sys_meta = utils.metadata_to_dict(result['system_metadata']) + self.assertEqual(sys_meta, {}) + + def test_instance_get_by_uuid_join_meta(self): + 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']) + meta = utils.metadata_to_dict(result['metadata']) + self.assertEqual(meta, fake_meta) + sys_meta = utils.metadata_to_dict(result['system_metadata']) + self.assertEqual(sys_meta, {}) + + def test_instance_get_by_uuid_join_sys_meta(self): + 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']) + meta = utils.metadata_to_dict(result['metadata']) + self.assertEqual(meta, {}) + sys_meta = utils.metadata_to_dict(result['system_metadata']) + self.assertEqual(sys_meta, fake_sys) + + def test_instance_get_all_by_filters_deleted(self): + 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)) + self.assertIn(inst1['id'], [result[0]['id'], result[1]['id']]) + self.assertIn(inst2['id'], [result[0]['id'], result[1]['id']]) + if inst1['id'] == result[0]['id']: + self.assertTrue(result[0]['deleted']) + 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_instance_with_args(system_metadata=sys_meta) + + elevated = self.context.elevated() + instances = db.instance_get_all_by_host_and_node(elevated, 'host1', + 'node1') + self.assertEqual(1, len(instances)) + instance = instances[0] + self.assertEqual(expected['uuid'], instance['uuid']) + sysmeta = dict(instance)['system_metadata'] + self.assertEqual(len(sysmeta), 0) + + def test_instance_get_all_hung_in_rebooting(self): + ctxt = context.get_admin_context() + + # Ensure no instances are returned. + results = db.instance_get_all_hung_in_rebooting(ctxt, 10) + self.assertEqual(0, len(results)) + + # Ensure one rebooting instance with updated_at older than 10 seconds + # is returned. + updated_at = datetime.datetime(2000, 1, 1, 12, 0, 0) + values = {"task_state": "rebooting", "updated_at": updated_at} + instance = db.instance_create(ctxt, values) + results = db.instance_get_all_hung_in_rebooting(ctxt, 10) + self.assertEqual(1, len(results)) + db.instance_update(ctxt, instance['uuid'], {"task_state": None}) + + # Ensure the newly rebooted instance is not returned. + updated_at = timeutils.utcnow() + values = {"task_state": "rebooting", "updated_at": updated_at} + instance = db.instance_create(ctxt, values) + results = db.instance_get_all_hung_in_rebooting(ctxt, 10) + self.assertEqual(0, len(results)) + db.instance_update(ctxt, instance['uuid'], {"task_state": None}) + + def test_instance_update_with_expected_vm_state(self): + ctxt = context.get_admin_context() + uuid = uuidutils.generate_uuid() + updates = {'expected_vm_state': 'meow', + 'moo': 'cow'} + + class FakeInstance(dict): + def save(self, session=None): + pass + + fake_instance_values = {'vm_state': 'meow', + 'hostname': '', + 'metadata': None, + 'system_metadata': None} + fake_instance = FakeInstance(fake_instance_values) + + self.mox.StubOutWithMock(sqlalchemy_api, '_instance_get_by_uuid') + self.mox.StubOutWithMock(fake_instance, 'save') + + sqlalchemy_api._instance_get_by_uuid(ctxt, uuid, + session=mox.IgnoreArg()).AndReturn(fake_instance) + fake_instance.save(session=mox.IgnoreArg()) + + self.mox.ReplayAll() + + result = db.instance_update(ctxt, uuid, updates) + expected_instance = dict(fake_instance_values) + expected_instance['moo'] = 'cow' + self.assertEqual(expected_instance, result) + + def test_instance_update_with_unexpected_vm_state(self): + ctxt = context.get_admin_context() + uuid = uuidutils.generate_uuid() + updates = {'expected_vm_state': 'meow'} + fake_instance = {'vm_state': 'nomatch'} + + self.mox.StubOutWithMock(sqlalchemy_api, '_instance_get_by_uuid') + + sqlalchemy_api._instance_get_by_uuid(ctxt, uuid, + session=mox.IgnoreArg()).AndReturn(fake_instance) + + self.mox.ReplayAll() + + self.assertRaises(exception.UnexpectedVMStateError, + db.instance_update, ctxt, uuid, updates) + + def test_instance_update_with_instance_uuid(self): + # test instance_update() works when an instance UUID is passed. + ctxt = context.get_admin_context() + + # Create an instance with some metadata + values = {'metadata': {'host': 'foo', 'key1': 'meow'}, + 'system_metadata': {'original_image_ref': 'blah'}} + instance = db.instance_create(ctxt, values) + + # Update the metadata + values = {'metadata': {'host': 'bar', 'key2': 'wuff'}, + 'system_metadata': {'original_image_ref': 'baz'}} + db.instance_update(ctxt, instance['uuid'], values) + + # Retrieve the user-provided metadata to ensure it was successfully + # updated + instance_meta = db.instance_metadata_get(ctxt, instance['uuid']) + self.assertEqual('bar', instance_meta['host']) + self.assertEqual('wuff', instance_meta['key2']) + self.assertNotIn('key1', instance_meta) + + # Retrieve the system metadata to ensure it was successfully updated + system_meta = db.instance_system_metadata_get(ctxt, instance['uuid']) + self.assertEqual('baz', system_meta['original_image_ref']) + + def test_delete_instance_metadata_on_instance_destroy(self): + ctxt = context.get_admin_context() + + # Create an instance with some metadata + values = {'metadata': {'host': 'foo', 'key1': 'meow'}, + 'system_metadata': {'original_image_ref': 'blah'}} + instance = db.instance_create(ctxt, values) + instance_meta = db.instance_metadata_get(ctxt, instance['uuid']) + self.assertEqual('foo', instance_meta['host']) + self.assertEqual('meow', instance_meta['key1']) + db.instance_destroy(ctxt, instance['uuid']) + instance_meta = db.instance_metadata_get(ctxt, instance['uuid']) + # Make sure instance metadata is deleted as well + self.assertEqual({}, instance_meta) + + def test_instance_update_unique_name(self): + otherprojectcontext = context.RequestContext(self.user_id, + "%s2" % self.project_id) + + inst = self.create_instance_with_args(hostname='fake_name') + uuid1p1 = inst['uuid'] + inst = self.create_instance_with_args(hostname='fake_name2') + uuid2p1 = inst['uuid'] + + inst = self.create_instance_with_args(context=otherprojectcontext, + hostname='fake_name3') + uuid1p2 = inst['uuid'] + + # osapi_compute_unique_server_name_scope is unset so this should work: + values = {'hostname': 'fake_name2'} + db.instance_update(self.context, uuid1p1, values) + values = {'hostname': 'fake_name'} + db.instance_update(self.context, uuid1p1, values) + + # With scope 'global' any duplicate should fail. + self.flags(osapi_compute_unique_server_name_scope='global') + self.assertRaises(exception.InstanceExists, + db.instance_update, + self.context, + uuid2p1, + values) + + self.assertRaises(exception.InstanceExists, + db.instance_update, + otherprojectcontext, + uuid1p2, + values) + + # But we should definitely be able to update our name if we aren't + # really changing it. + case_only_values = {'hostname': 'fake_NAME'} + db.instance_update(self.context, uuid1p1, case_only_values) + + # With scope 'project' a duplicate in the project should fail: + self.flags(osapi_compute_unique_server_name_scope='project') + self.assertRaises(exception.InstanceExists, + db.instance_update, + self.context, + uuid2p1, + values) + + # With scope 'project' a duplicate in a different project should work: + self.flags(osapi_compute_unique_server_name_scope='project') + db.instance_update(otherprojectcontext, uuid1p2, values) + + def test_instance_update_with_and_get_original(self): + ctxt = context.get_admin_context() + + # Create an instance with some metadata + values = {'vm_state': 'building'} + instance = db.instance_create(ctxt, values) + + (old_ref, new_ref) = db.instance_update_and_get_original(ctxt, + instance['uuid'], {'vm_state': 'needscoffee'}) + self.assertEquals("building", old_ref["vm_state"]) + self.assertEquals("needscoffee", new_ref["vm_state"]) + + def _test_instance_update_updates_metadata(self, metadata_type): + ctxt = context.get_admin_context() + + instance = db.instance_create(ctxt, {}) + + def set_and_check(meta): + inst = db.instance_update(ctxt, instance['uuid'], + {metadata_type: dict(meta)}) + _meta = utils.metadata_to_dict(inst[metadata_type]) + self.assertEqual(meta, _meta) + + meta = {'speed': '88', 'units': 'MPH'} + set_and_check(meta) + + meta['gigawatts'] = '1.21' + set_and_check(meta) + + del meta['gigawatts'] + set_and_check(meta) + + def test_instance_update_updates_system_metadata(self): + # Ensure that system_metadata is updated during instance_update + self._test_instance_update_updates_metadata('system_metadata') + + def test_instance_update_updates_metadata(self): + # Ensure that metadata is updated during instance_update + self._test_instance_update_updates_metadata('metadata') + + def test_instance_floating_address_get_all(self): + ctxt = context.get_admin_context() + + instance1 = db.instance_create(ctxt, {'host': 'h1', 'hostname': 'n1'}) + instance2 = db.instance_create(ctxt, {'host': 'h2', 'hostname': 'n2'}) + + fixed_addresses = ['1.1.1.1', '1.1.1.2', '1.1.1.3'] + float_addresses = ['2.1.1.1', '2.1.1.2', '2.1.1.3'] + instance_uuids = [instance1['uuid'], instance1['uuid'], + instance2['uuid']] + + for fixed_addr, float_addr, instance_uuid in zip(fixed_addresses, + float_addresses, + instance_uuids): + db.fixed_ip_create(ctxt, {'address': fixed_addr, + 'instance_uuid': instance_uuid}) + fixed_id = db.fixed_ip_get_by_address(ctxt, fixed_addr)['id'] + db.floating_ip_create(ctxt, + {'address': float_addr, + 'fixed_ip_id': fixed_id}) + + real_float_addresses = \ + db.instance_floating_address_get_all(ctxt, instance_uuids[0]) + self.assertEqual(set(float_addresses[:2]), set(real_float_addresses)) + real_float_addresses = \ + db.instance_floating_address_get_all(ctxt, instance_uuids[2]) + self.assertEqual(set([float_addresses[2]]), set(real_float_addresses)) + + class InstanceMetadataTestCase(test.TestCase): """Tests for db.api.instance_metadata_* methods.""" @@ -1896,7 +1904,7 @@ class ServiceTestCase(test.TestCase, ModelsObjectComparatorMixin): def test_service_get(self): service1 = self._create_service({}) - service2 = self._create_service({'host': 'some_other_fake_host'}) + self._create_service({'host': 'some_other_fake_host'}) real_service1 = db.service_get(self.ctxt, service1['id']) self._assertEqualObjects(service1, real_service1, ignored_keys=['compute_node']) @@ -1921,7 +1929,7 @@ class ServiceTestCase(test.TestCase, ModelsObjectComparatorMixin): def test_service_get_by_host_and_topic(self): service1 = self._create_service({'host': 'host1', 'topic': 'topic1'}) - service2 = self._create_service({'host': 'host2', 'topic': 'topic2'}) + self._create_service({'host': 'host2', 'topic': 'topic2'}) real_service1 = db.service_get_by_host_and_topic(self.ctxt, host='host1', @@ -3693,24 +3701,24 @@ class VolumeUsageDBApiTestCase(test.TestCase): vol_usages = db.vol_get_usage_by_time(ctxt, start_time) self.assertEqual(len(vol_usages), 0) - vol_usage = db.vol_usage_update(ctxt, 1, rd_req=10, rd_bytes=20, - wr_req=30, wr_bytes=40, - instance_id='fake-instance-uuid1', - project_id='fake-project-uuid1', - user_id='fake-user-uuid1', - availability_zone='fake-az') - vol_usage = db.vol_usage_update(ctxt, 2, rd_req=100, rd_bytes=200, - wr_req=300, wr_bytes=400, - instance_id='fake-instance-uuid2', - project_id='fake-project-uuid2', - user_id='fake-user-uuid2', - availability_zone='fake-az') - vol_usage = db.vol_usage_update(ctxt, 1, rd_req=1000, rd_bytes=2000, - wr_req=3000, wr_bytes=4000, - instance_id='fake-instance-uuid1', - project_id='fake-project-uuid1', - user_id='fake-user-uuid1', - availability_zone='fake-az') + db.vol_usage_update(ctxt, 1, rd_req=10, rd_bytes=20, + wr_req=30, wr_bytes=40, + instance_id='fake-instance-uuid1', + project_id='fake-project-uuid1', + user_id='fake-user-uuid1', + availability_zone='fake-az') + db.vol_usage_update(ctxt, 2, rd_req=100, rd_bytes=200, + wr_req=300, wr_bytes=400, + instance_id='fake-instance-uuid2', + project_id='fake-project-uuid2', + user_id='fake-user-uuid2', + availability_zone='fake-az') + db.vol_usage_update(ctxt, 1, rd_req=1000, rd_bytes=2000, + wr_req=3000, wr_bytes=4000, + instance_id='fake-instance-uuid1', + project_id='fake-project-uuid1', + user_id='fake-user-uuid1', + availability_zone='fake-az') vol_usages = db.vol_get_usage_by_time(ctxt, start_time) self.assertEqual(len(vol_usages), 2) @@ -3732,44 +3740,44 @@ class VolumeUsageDBApiTestCase(test.TestCase): timeutils.utcnow().AndReturn(now3) self.mox.ReplayAll() - vol_usage = db.vol_usage_update(ctxt, 1, rd_req=100, rd_bytes=200, - wr_req=300, wr_bytes=400, - instance_id='fake-instance-uuid', - project_id='fake-project-uuid', - user_id='fake-user-uuid', - availability_zone='fake-az') + db.vol_usage_update(ctxt, 1, rd_req=100, rd_bytes=200, + wr_req=300, wr_bytes=400, + instance_id='fake-instance-uuid', + project_id='fake-project-uuid', + user_id='fake-user-uuid', + availability_zone='fake-az') current_usage = db.vol_get_usage_by_time(ctxt, start_time)[0] self.assertEqual(current_usage['tot_reads'], 0) self.assertEqual(current_usage['curr_reads'], 100) - vol_usage = db.vol_usage_update(ctxt, 1, rd_req=200, rd_bytes=300, - wr_req=400, wr_bytes=500, - instance_id='fake-instance-uuid', - project_id='fake-project-uuid', - user_id='fake-user-uuid', - availability_zone='fake-az', - update_totals=True) + db.vol_usage_update(ctxt, 1, rd_req=200, rd_bytes=300, + wr_req=400, wr_bytes=500, + instance_id='fake-instance-uuid', + project_id='fake-project-uuid', + user_id='fake-user-uuid', + availability_zone='fake-az', + update_totals=True) current_usage = db.vol_get_usage_by_time(ctxt, start_time)[0] self.assertEqual(current_usage['tot_reads'], 200) self.assertEqual(current_usage['curr_reads'], 0) - vol_usage = db.vol_usage_update(ctxt, 1, rd_req=300, rd_bytes=400, - wr_req=500, wr_bytes=600, - instance_id='fake-instance-uuid', - project_id='fake-project-uuid', - availability_zone='fake-az', - user_id='fake-user-uuid') + db.vol_usage_update(ctxt, 1, rd_req=300, rd_bytes=400, + wr_req=500, wr_bytes=600, + instance_id='fake-instance-uuid', + project_id='fake-project-uuid', + availability_zone='fake-az', + user_id='fake-user-uuid') current_usage = db.vol_get_usage_by_time(ctxt, start_time)[0] self.assertEqual(current_usage['tot_reads'], 200) self.assertEqual(current_usage['curr_reads'], 300) - vol_usage = db.vol_usage_update(ctxt, 1, rd_req=400, rd_bytes=500, - wr_req=600, wr_bytes=700, - instance_id='fake-instance-uuid', - project_id='fake-project-uuid', - user_id='fake-user-uuid', - availability_zone='fake-az', - update_totals=True) + db.vol_usage_update(ctxt, 1, rd_req=400, rd_bytes=500, + wr_req=600, wr_bytes=700, + instance_id='fake-instance-uuid', + project_id='fake-project-uuid', + user_id='fake-user-uuid', + availability_zone='fake-az', + update_totals=True) vol_usages = db.vol_get_usage_by_time(ctxt, start_time) @@ -3986,12 +3994,15 @@ class BlockDeviceMappingTestCase(test.TestCase): def test_block_device_mapping_update(self): bdm = self._create_bdm({}) - db.block_device_mapping_update(self.ctxt, bdm['id'], - {'destination_type': 'moon'}, - legacy=False) + result = db.block_device_mapping_update( + self.ctxt, bdm['id'], {'destination_type': 'moon'}, + legacy=False) uuid = bdm['instance_uuid'] bdm_real = db.block_device_mapping_get_all_by_instance(self.ctxt, uuid) self.assertEqual(bdm_real[0]['destination_type'], 'moon') + # Also make sure the update call returned correct data + self.assertEqual(dict(bdm_real[0].iteritems()), + dict(result.iteritems())) def test_block_device_mapping_update_or_create(self): values = { @@ -4711,7 +4722,7 @@ class QuotaTestCase(test.TestCase, ModelsObjectComparatorMixin): self.ctxt, 'p1', 'nonexitent_resource') def test_quota_usage_get(self): - reservations = _quota_reserve(self.ctxt, 'p1') + _quota_reserve(self.ctxt, 'p1') quota_usage = db.quota_usage_get(self.ctxt, 'p1', 'res0') expected = {'resource': 'res0', 'project_id': 'p1', 'in_use': 0, 'reserved': 0, 'total': 0} @@ -4719,7 +4730,7 @@ class QuotaTestCase(test.TestCase, ModelsObjectComparatorMixin): self.assertEqual(value, quota_usage[key]) def test_quota_usage_get_all_by_project(self): - reservations = _quota_reserve(self.ctxt, 'p1') + _quota_reserve(self.ctxt, 'p1') expected = {'project_id': 'p1', 'res0': {'in_use': 0, 'reserved': 0}, 'res1': {'in_use': 1, 'reserved': 1}, @@ -4732,8 +4743,7 @@ class QuotaTestCase(test.TestCase, ModelsObjectComparatorMixin): self.ctxt, 'p1', 'resource', in_use=42) def test_quota_usage_update(self): - reservations = _quota_reserve(self.ctxt, 'p1') - until_refresh = datetime.datetime.now() + datetime.timedelta(days=1) + _quota_reserve(self.ctxt, 'p1') db.quota_usage_update(self.ctxt, 'p1', 'res0', in_use=42, reserved=43) quota_usage = db.quota_usage_get(self.ctxt, 'p1', 'res0') expected = {'resource': 'res0', 'project_id': 'p1', @@ -4789,7 +4799,7 @@ class QuotaClassTestCase(test.TestCase, ModelsObjectComparatorMixin): 'resource0': 0, 'resource1': 1, 'resource2': 2}) def test_quota_class_update(self): - qc = db.quota_class_create(self.ctxt, 'class name', 'resource', 42) + db.quota_class_create(self.ctxt, 'class name', 'resource', 42) db.quota_class_update(self.ctxt, 'class name', 'resource', 43) self.assertEqual(db.quota_class_get(self.ctxt, 'class name', 'resource').hard_limit, 43) @@ -4948,6 +4958,19 @@ class ComputeNodeTestCase(test.TestCase, ModelsObjectComparatorMixin): self.assertNotEqual(self.item['updated_at'], item_updated['updated_at']) + def test_compute_node_update_override_updated_at(self): + # Update the record once so updated_at is set. + first = db.compute_node_update(self.ctxt, self.item['id'], + {'free_ram_mb': '12'}) + self.assertIsNotNone(first['updated_at']) + + # Update a second time. Make sure that the updated_at value we send + # is overridden. + second = db.compute_node_update(self.ctxt, self.item['id'], + {'updated_at': first.updated_at, + 'free_ram_mb': '13'}) + self.assertNotEqual(first['updated_at'], second['updated_at']) + def test_compute_node_stat_unchanged(self): # don't update unchanged stat values: stats = self.item['stats'] |