31
32
FLAGS = flags.FLAGS
34
def _setup_networking(instance_id, ip='1.2.3.4', flo_addr='1.2.1.2'):
35
ctxt = context.get_admin_context()
36
network_ref = db.project_get_networks(ctxt,
39
vif = {'address': '56:12:12:12:12:12',
40
'network_id': network_ref['id'],
41
'instance_id': instance_id}
42
vif_ref = db.virtual_interface_create(ctxt, vif)
44
fixed_ip = {'address': ip,
45
'network_id': network_ref['id'],
46
'virtual_interface_id': vif_ref['id'],
48
'instance_id': instance_id}
49
db.fixed_ip_create(ctxt, fixed_ip)
50
fix_ref = db.fixed_ip_get_by_address(ctxt, ip)
51
db.floating_ip_create(ctxt, {'address': flo_addr,
52
'fixed_ip_id': fix_ref['id']})
55
35
class DbApiTestCase(test.TestCase):
57
37
super(DbApiTestCase, self).setUp()
59
39
self.project_id = 'fake'
60
40
self.context = context.RequestContext(self.user_id, self.project_id)
42
def create_instances_with_args(self, **kwargs):
43
args = {'reservation_id': 'a', 'image_ref': 1, 'host': 'host1',
44
'project_id': self.project_id}
46
return db.instance_create(self.context, args)
48
def test_ec2_ids_not_found_are_printable(self):
50
def check_exc_format(method):
52
method(self.context, 'fake')
53
except Exception as exc:
54
self.assertTrue('fake' in unicode(exc))
56
check_exc_format(db.get_ec2_volume_id_by_uuid)
57
check_exc_format(db.get_volume_uuid_by_ec2_id)
58
check_exc_format(db.get_ec2_snapshot_id_by_uuid)
59
check_exc_format(db.get_snapshot_uuid_by_ec2_id)
60
check_exc_format(db.get_ec2_instance_id_by_uuid)
61
check_exc_format(db.get_instance_uuid_by_ec2_id)
62
63
def test_instance_get_all_by_filters(self):
63
args = {'reservation_id': 'a', 'image_ref': 1, 'host': 'host1'}
64
db.instance_create(self.context, args)
65
db.instance_create(self.context, args)
64
self.create_instances_with_args()
65
self.create_instances_with_args()
66
66
result = db.instance_get_all_by_filters(self.context, {})
67
self.assertTrue(2, len(result))
67
self.assertEqual(2, len(result))
69
def test_instance_get_all_by_filters_regex(self):
70
self.create_instances_with_args(display_name='test1')
71
self.create_instances_with_args(display_name='teeeest2')
72
self.create_instances_with_args(display_name='diff')
73
result = db.instance_get_all_by_filters(self.context,
74
{'display_name': 't.*st.'})
75
self.assertEqual(2, len(result))
77
def test_instance_get_all_by_filters_regex_unsupported_db(self):
78
"""Ensure that the 'LIKE' operator is used for unsupported dbs."""
79
self.flags(sql_connection="notdb://")
80
self.create_instances_with_args(display_name='test1')
81
self.create_instances_with_args(display_name='test.*')
82
self.create_instances_with_args(display_name='diff')
83
result = db.instance_get_all_by_filters(self.context,
84
{'display_name': 'test.*'})
85
self.assertEqual(1, len(result))
86
result = db.instance_get_all_by_filters(self.context,
87
{'display_name': '%test%'})
88
self.assertEqual(2, len(result))
90
def test_instance_get_all_by_filters_metadata(self):
91
self.create_instances_with_args(metadata={'foo': 'bar'})
92
self.create_instances_with_args()
93
result = db.instance_get_all_by_filters(self.context,
94
{'metadata': {'foo': 'bar'}})
95
self.assertEqual(1, len(result))
97
def test_instance_get_all_by_filters_unicode_value(self):
98
self.create_instances_with_args(display_name=u'testā„')
99
result = db.instance_get_all_by_filters(self.context,
100
{'display_name': u'test'})
101
self.assertEqual(1, len(result))
69
103
def test_instance_get_all_by_filters_deleted(self):
70
args1 = {'reservation_id': 'a', 'image_ref': 1, 'host': 'host1'}
71
inst1 = db.instance_create(self.context, args1)
72
args2 = {'reservation_id': 'b', 'image_ref': 1, 'host': 'host1'}
73
inst2 = db.instance_create(self.context, args2)
74
db.instance_destroy(self.context.elevated(), inst1['uuid'])
75
result = db.instance_get_all_by_filters(self.context.elevated(), {})
104
inst1 = self.create_instances_with_args()
105
inst2 = self.create_instances_with_args(reservation_id='b')
106
db.instance_destroy(self.context, inst1['uuid'])
107
result = db.instance_get_all_by_filters(self.context, {})
76
108
self.assertEqual(2, len(result))
77
109
self.assertIn(inst1.id, [result[0].id, result[1].id])
78
110
self.assertIn(inst2.id, [result[0].id, result[1].id])
82
114
self.assertTrue(result[1].deleted)
84
def test_migration_get_all_unconfirmed(self):
116
def test_migration_get_unconfirmed_by_dest_compute(self):
85
117
ctxt = context.get_admin_context()
87
119
# Ensure no migrations are returned.
88
results = db.migration_get_all_unconfirmed(ctxt, 10)
120
results = db.migration_get_unconfirmed_by_dest_compute(ctxt, 10,
122
self.assertEqual(0, len(results))
124
# Ensure no migrations are returned.
125
results = db.migration_get_unconfirmed_by_dest_compute(ctxt, 10,
127
self.assertEqual(0, len(results))
129
updated_at = datetime.datetime(2000, 01, 01, 12, 00, 00)
130
values = {"status": "finished", "updated_at": updated_at,
131
"dest_compute": "fake_host2"}
132
migration = db.migration_create(ctxt, values)
134
# Ensure different host is not returned
135
results = db.migration_get_unconfirmed_by_dest_compute(ctxt, 10,
89
137
self.assertEqual(0, len(results))
91
139
# Ensure one migration older than 10 seconds is returned.
92
updated_at = datetime.datetime(2000, 01, 01, 12, 00, 00)
93
values = {"status": "finished", "updated_at": updated_at}
94
migration = db.migration_create(ctxt, values)
95
results = db.migration_get_all_unconfirmed(ctxt, 10)
140
results = db.migration_get_unconfirmed_by_dest_compute(ctxt, 10,
96
142
self.assertEqual(1, len(results))
97
143
db.migration_update(ctxt, migration.id, {"status": "CONFIRMED"})
99
145
# Ensure the new migration is not returned.
100
146
updated_at = timeutils.utcnow()
101
values = {"status": "finished", "updated_at": updated_at}
147
values = {"status": "finished", "updated_at": updated_at,
148
"dest_compute": "fake_host2"}
102
149
migration = db.migration_create(ctxt, values)
103
results = db.migration_get_all_unconfirmed(ctxt, 10)
150
results = db.migration_get_unconfirmed_by_dest_compute(ctxt, 10,
104
152
self.assertEqual(0, len(results))
105
153
db.migration_update(ctxt, migration.id, {"status": "CONFIRMED"})
329
377
ctxt = context.get_admin_context()
330
378
values = {'host': 'foo', 'hostname': 'myname'}
331
379
instance = db.instance_create(ctxt, values)
332
values = {'address': 'bar', 'instance_id': instance['id']}
380
values = {'address': 'bar', 'instance_uuid': instance['uuid']}
333
381
vif = db.virtual_interface_create(ctxt, values)
334
382
values = {'address': 'baz',
336
384
'allocated': True,
337
'instance_id': instance['id'],
385
'instance_uuid': instance['uuid'],
338
386
'virtual_interface_id': vif['id']}
339
387
fixed_address = db.fixed_ip_create(ctxt, values)
340
388
data = db.network_get_associated_fixed_ips(ctxt, 1)
341
389
self.assertEqual(len(data), 1)
343
391
self.assertEqual(record['address'], fixed_address)
344
self.assertEqual(record['instance_id'], instance['id'])
392
self.assertEqual(record['instance_uuid'], instance['uuid'])
345
393
self.assertEqual(record['network_id'], 1)
346
394
self.assertEqual(record['instance_created'], instance['created_at'])
347
395
self.assertEqual(record['instance_updated'], instance['updated_at'])
360
408
new = time = timeout + datetime.timedelta(seconds=5)
361
409
# should deallocate
362
410
values = {'allocated': False,
363
'instance_id': instance['id'],
411
'instance_uuid': instance['uuid'],
364
412
'network_id': net['id'],
365
413
'updated_at': old}
366
414
db.fixed_ip_create(ctxt, values)
367
415
# still allocated
368
416
values = {'allocated': True,
369
'instance_id': instance['id'],
417
'instance_uuid': instance['uuid'],
370
418
'network_id': net['id'],
371
419
'updated_at': old}
372
420
db.fixed_ip_create(ctxt, values)
374
422
values = {'allocated': False,
375
'instance_id': instance['id'],
423
'instance_uuid': instance['uuid'],
376
424
'network_id': None,
377
425
'updated_at': old}
378
426
db.fixed_ip_create(ctxt, values)
380
428
values = {'allocated': False,
381
'instance_id': instance['id'],
429
'instance_uuid': instance['uuid'],
382
430
'network_id': None,
383
431
'updated_at': new}
384
432
db.fixed_ip_create(ctxt, values)
411
459
ec2_id = db.get_ec2_snapshot_id_by_uuid(self.context, 'fake-uuid')
412
460
self.assertEqual(ref['id'], ec2_id)
462
def test_bw_usage_calls(self):
463
ctxt = context.get_admin_context()
464
now = timeutils.utcnow()
465
timeutils.set_time_override(now)
466
start_period = now - datetime.timedelta(seconds=10)
467
uuid3_refreshed = now - datetime.timedelta(seconds=5)
469
expected_bw_usages = [{'uuid': 'fake_uuid1',
471
'start_period': start_period,
474
'last_refreshed': now},
475
{'uuid': 'fake_uuid2',
477
'start_period': start_period,
480
'last_refreshed': now},
481
{'uuid': 'fake_uuid3',
483
'start_period': start_period,
486
'last_refreshed': uuid3_refreshed}]
488
def _compare(bw_usage, expected):
489
for key, value in expected.items():
490
self.assertEqual(bw_usage[key], value)
492
bw_usages = db.bw_usage_get_by_uuids(ctxt,
493
['fake_uuid1', 'fake_uuid2'], start_period)
495
self.assertEqual(len(bw_usages), 0)
498
db.bw_usage_update(ctxt, 'fake_uuid1',
499
'fake_mac1', start_period,
501
db.bw_usage_update(ctxt, 'fake_uuid2',
502
'fake_mac2', start_period,
504
# Test explicit refreshed time
505
db.bw_usage_update(ctxt, 'fake_uuid3',
506
'fake_mac3', start_period,
507
400, 500, last_refreshed=uuid3_refreshed)
509
db.bw_usage_update(ctxt, 'fake_uuid2',
510
'fake_mac2', start_period,
513
bw_usages = db.bw_usage_get_by_uuids(ctxt,
514
['fake_uuid1', 'fake_uuid2', 'fake_uuid3'], start_period)
515
self.assertEqual(len(bw_usages), 3)
516
_compare(bw_usages[0], expected_bw_usages[0])
517
_compare(bw_usages[1], expected_bw_usages[1])
518
_compare(bw_usages[2], expected_bw_usages[2])
519
timeutils.clear_time_override()
415
522
def _get_fake_aggr_values():
416
523
return {'name': 'fake_aggregate',
511
617
self.assertEqual(_get_fake_aggr_metadata(), expected.metadetails)
513
619
def test_aggregate_get_by_host(self):
514
"""Ensure we can get an aggregate by host."""
515
ctxt = context.get_admin_context()
516
r1 = _create_aggregate_with_hosts(context=ctxt)
517
r2 = db.aggregate_get_by_host(ctxt, 'foo.openstack.org')
518
self.assertEqual(r1.id, r2.id)
620
"""Ensure we can get aggregates by host."""
621
ctxt = context.get_admin_context()
622
values = {'name': 'fake_aggregate2',
623
'availability_zone': 'fake_avail_zone', }
624
a1 = _create_aggregate_with_hosts(context=ctxt)
625
a2 = _create_aggregate_with_hosts(context=ctxt, values=values)
626
r1 = db.aggregate_get_by_host(ctxt, 'foo.openstack.org')
627
self.assertEqual([a1.id, a2.id], [x.id for x in r1])
629
def test_aggregate_get_by_host_with_key(self):
630
"""Ensure we can get aggregates by host."""
631
ctxt = context.get_admin_context()
632
values = {'name': 'fake_aggregate2',
633
'availability_zone': 'fake_avail_zone', }
634
a1 = _create_aggregate_with_hosts(context=ctxt,
635
metadata={'goodkey': 'good'})
636
a2 = _create_aggregate_with_hosts(context=ctxt, values=values)
637
# filter result by key
638
r1 = db.aggregate_get_by_host(ctxt, 'foo.openstack.org', key='goodkey')
639
self.assertEqual([a1.id], [x.id for x in r1])
641
def test_aggregate_metdata_get_by_host(self):
642
"""Ensure we can get aggregates by host."""
643
ctxt = context.get_admin_context()
644
values = {'name': 'fake_aggregate2',
645
'availability_zone': 'fake_avail_zone', }
646
values2 = {'name': 'fake_aggregate3',
647
'availability_zone': 'fake_avail_zone', }
648
a1 = _create_aggregate_with_hosts(context=ctxt)
649
a2 = _create_aggregate_with_hosts(context=ctxt, values=values)
650
a3 = _create_aggregate_with_hosts(context=ctxt, values=values2,
651
hosts=['bar.openstack.org'], metadata={'badkey': 'bad'})
652
r1 = db.aggregate_metadata_get_by_host(ctxt, 'foo.openstack.org')
653
self.assertEqual(r1['fake_key1'], set(['fake_value1']))
654
self.assertFalse('badkey' in r1)
656
def test_aggregate_metdata_get_by_host_with_key(self):
657
"""Ensure we can get aggregates by host."""
658
ctxt = context.get_admin_context()
659
values = {'name': 'fake_aggregate2',
660
'availability_zone': 'fake_avail_zone', }
661
values2 = {'name': 'fake_aggregate3',
662
'availability_zone': 'fake_avail_zone', }
663
a1 = _create_aggregate_with_hosts(context=ctxt)
664
a2 = _create_aggregate_with_hosts(context=ctxt, values=values)
665
a3 = _create_aggregate_with_hosts(context=ctxt, values=values2,
666
hosts=['foo.openstack.org'], metadata={'good': 'value'})
667
r1 = db.aggregate_metadata_get_by_host(ctxt, 'foo.openstack.org',
669
self.assertEqual(r1['good'], set(['value']))
670
self.assertFalse('fake_key1' in r1)
672
db.aggregate_metadata_delete(ctxt, a3.id, 'good')
673
r2 = db.aggregate_metadata_get_by_host(ctxt, 'foo.openstack.org',
675
self.assertFalse('good' in r2)
520
677
def test_aggregate_get_by_host_not_found(self):
521
678
"""Ensure AggregateHostNotFound is raised with unknown host."""
522
679
ctxt = context.get_admin_context()
523
680
_create_aggregate_with_hosts(context=ctxt)
524
self.assertRaises(exception.AggregateHostNotFound,
525
db.aggregate_get_by_host, ctxt, 'unknown_host')
681
self.assertEqual([], db.aggregate_get_by_host(ctxt, 'unknown_host'))
527
683
def test_aggregate_delete_raise_not_found(self):
528
684
"""Ensure AggregateNotFound is raised when deleting an aggregate."""
670
826
expected = db.aggregate_host_get_all(ctxt, result.id)
671
827
self.assertEqual(len(expected), 1)
673
def test_aggregate_host_add_duplicate_raise_conflict(self):
674
"""Ensure we cannot add host to distinct aggregates."""
829
def test_aggregate_host_add_duplicate_works(self):
830
"""Ensure we can add host to distinct aggregates."""
675
831
ctxt = context.get_admin_context()
676
_create_aggregate_with_hosts(context=ctxt, metadata=None)
677
self.assertRaises(exception.AggregateHostConflict,
678
_create_aggregate_with_hosts, ctxt,
832
r1 = _create_aggregate_with_hosts(context=ctxt, metadata=None)
833
r2 = _create_aggregate_with_hosts(ctxt,
679
834
values={'name': 'fake_aggregate2',
680
835
'availability_zone': 'fake_avail_zone2', },
837
h1 = db.aggregate_host_get_all(ctxt, r1.id)
838
h2 = db.aggregate_host_get_all(ctxt, r2.id)
839
self.assertEqual(h1, h2)
683
841
def test_aggregate_host_add_duplicate_raise_exist_exc(self):
684
842
"""Ensure we cannot add host to the same aggregate."""
829
987
def test_fixed_ip_associate_fails_if_ip_not_in_network(self):
830
988
self.assertRaises(exception.FixedIpNotFoundForNetwork,
831
989
db.fixed_ip_associate,
832
self.ctxt, None, None)
990
self.ctxt, None, self.instance.uuid)
834
992
def test_fixed_ip_associate_fails_if_ip_in_use(self):
835
address = self.create_fixed_ip(instance_id=self.instance.id)
993
address = self.create_fixed_ip(instance_uuid=self.instance.uuid)
836
994
self.assertRaises(exception.FixedIpAlreadyInUse,
837
995
db.fixed_ip_associate,
838
self.ctxt, address, self.instance.id)
996
self.ctxt, address, self.instance.uuid)
840
998
def test_fixed_ip_associate_succeeds(self):
841
999
address = self.create_fixed_ip(network_id=self.network.id)
842
db.fixed_ip_associate(self.ctxt, address, self.instance.id,
1000
db.fixed_ip_associate(self.ctxt, address, self.instance.uuid,
843
1001
network_id=self.network.id)
844
1002
fixed_ip = db.fixed_ip_get_by_address(self.ctxt, address)
845
self.assertEqual(fixed_ip.instance_id, self.instance.id)
1003
self.assertEqual(fixed_ip.instance_uuid, self.instance.uuid)
847
1005
def test_fixed_ip_associate_succeeds_and_sets_network(self):
848
1006
address = self.create_fixed_ip()
849
db.fixed_ip_associate(self.ctxt, address, self.instance.id,
1007
db.fixed_ip_associate(self.ctxt, address, self.instance.uuid,
850
1008
network_id=self.network.id)
851
1009
fixed_ip = db.fixed_ip_get_by_address(self.ctxt, address)
852
self.assertEqual(fixed_ip.instance_id, self.instance.id)
1010
self.assertEqual(fixed_ip.instance_uuid, self.instance.uuid)
853
1011
self.assertEqual(fixed_ip.network_id, self.network.id)