~ubuntu-branches/ubuntu/quantal/nova/quantal-proposed

« back to all changes in this revision

Viewing changes to nova/tests/test_db_api.py

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2012-08-16 14:04:11 UTC
  • mto: This revision was merged to the branch mainline in revision 84.
  • Revision ID: package-import@ubuntu.com-20120816140411-0mr4n241wmk30t9l
Tags: upstream-2012.2~f3
ImportĀ upstreamĀ versionĀ 2012.2~f3

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
# vim: tabstop=4 shiftwidth=4 softtabstop=4
 
2
# encoding=UTF8
2
3
 
3
4
# Copyright 2010 United States Government as represented by the
4
5
# Administrator of the National Aeronautics and Space Administration.
31
32
FLAGS = flags.FLAGS
32
33
 
33
34
 
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,
37
 
                                           'fake',
38
 
                                           associate=True)[0]
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)
43
 
 
44
 
    fixed_ip = {'address': ip,
45
 
                'network_id': network_ref['id'],
46
 
                'virtual_interface_id': vif_ref['id'],
47
 
                'allocated': True,
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']})
53
 
 
54
 
 
55
35
class DbApiTestCase(test.TestCase):
56
36
    def setUp(self):
57
37
        super(DbApiTestCase, self).setUp()
59
39
        self.project_id = 'fake'
60
40
        self.context = context.RequestContext(self.user_id, self.project_id)
61
41
 
 
42
    def create_instances_with_args(self, **kwargs):
 
43
        args = {'reservation_id': 'a', 'image_ref': 1, 'host': 'host1',
 
44
                'project_id': self.project_id}
 
45
        args.update(kwargs)
 
46
        return db.instance_create(self.context, args)
 
47
 
 
48
    def test_ec2_ids_not_found_are_printable(self):
 
49
 
 
50
        def check_exc_format(method):
 
51
            try:
 
52
                method(self.context, 'fake')
 
53
            except Exception as exc:
 
54
                self.assertTrue('fake' in unicode(exc))
 
55
 
 
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
 
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))
 
68
 
 
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))
 
76
 
 
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))
 
89
 
 
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))
 
96
 
 
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))
68
102
 
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])
81
113
        else:
82
114
            self.assertTrue(result[1].deleted)
83
115
 
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()
86
118
 
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,
 
121
                'fake_host')
 
122
        self.assertEqual(0, len(results))
 
123
 
 
124
        # Ensure no migrations are returned.
 
125
        results = db.migration_get_unconfirmed_by_dest_compute(ctxt, 10,
 
126
                'fake_host2')
 
127
        self.assertEqual(0, len(results))
 
128
 
 
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)
 
133
 
 
134
        # Ensure different host is not returned
 
135
        results = db.migration_get_unconfirmed_by_dest_compute(ctxt, 10,
 
136
                'fake_host')
89
137
        self.assertEqual(0, len(results))
90
138
 
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,
 
141
                'fake_host2')
96
142
        self.assertEqual(1, len(results))
97
143
        db.migration_update(ctxt, migration.id, {"status": "CONFIRMED"})
98
144
 
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,
 
151
                "fake_host2")
104
152
        self.assertEqual(0, len(results))
105
153
        db.migration_update(ctxt, migration.id, {"status": "CONFIRMED"})
106
154
 
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',
335
383
                  'network_id': 1,
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)
342
390
        record = data[0]
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)
373
421
        # wrong network
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)
379
427
        # too new
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)
413
461
 
 
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)
 
468
 
 
469
        expected_bw_usages = [{'uuid': 'fake_uuid1',
 
470
                               'mac': 'fake_mac1',
 
471
                               'start_period': start_period,
 
472
                               'bw_in': 100,
 
473
                               'bw_out': 200,
 
474
                               'last_refreshed': now},
 
475
                              {'uuid': 'fake_uuid2',
 
476
                               'mac': 'fake_mac2',
 
477
                               'start_period': start_period,
 
478
                               'bw_in': 200,
 
479
                               'bw_out': 300,
 
480
                               'last_refreshed': now},
 
481
                              {'uuid': 'fake_uuid3',
 
482
                               'mac': 'fake_mac3',
 
483
                               'start_period': start_period,
 
484
                               'bw_in': 400,
 
485
                               'bw_out': 500,
 
486
                               'last_refreshed': uuid3_refreshed}]
 
487
 
 
488
        def _compare(bw_usage, expected):
 
489
            for key, value in expected.items():
 
490
                self.assertEqual(bw_usage[key], value)
 
491
 
 
492
        bw_usages = db.bw_usage_get_by_uuids(ctxt,
 
493
                ['fake_uuid1', 'fake_uuid2'], start_period)
 
494
        # No matches
 
495
        self.assertEqual(len(bw_usages), 0)
 
496
 
 
497
        # Add 3 entries
 
498
        db.bw_usage_update(ctxt, 'fake_uuid1',
 
499
                'fake_mac1', start_period,
 
500
                100, 200)
 
501
        db.bw_usage_update(ctxt, 'fake_uuid2',
 
502
                'fake_mac2', start_period,
 
503
                100, 200)
 
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)
 
508
        # Update 2nd entry
 
509
        db.bw_usage_update(ctxt, 'fake_uuid2',
 
510
                'fake_mac2', start_period,
 
511
                200, 300)
 
512
 
 
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()
 
520
 
414
521
 
415
522
def _get_fake_aggr_values():
416
523
    return {'name': 'fake_aggregate',
453
560
    def test_aggregate_create(self):
454
561
        """Ensure aggregate can be created with no metadata."""
455
562
        result = _create_aggregate(metadata=None)
456
 
        self.assertEqual(result['operational_state'], 'created')
 
563
        self.assertEquals(result.name, 'fake_aggregate')
457
564
 
458
565
    def test_aggregate_create_avoid_name_conflict(self):
459
566
        """Test we can avoid conflict on deleted aggregates."""
463
570
        r2 = _create_aggregate(values=values)
464
571
        self.assertEqual(r2.name, values['name'])
465
572
        self.assertEqual(r2.availability_zone, values['availability_zone'])
466
 
        self.assertEqual(r2.operational_state, "created")
467
573
 
468
574
    def test_aggregate_create_raise_exist_exc(self):
469
575
        """Ensure aggregate names are distinct."""
511
617
        self.assertEqual(_get_fake_aggr_metadata(), expected.metadetails)
512
618
 
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])
 
628
 
 
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])
 
640
 
 
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)
 
655
 
 
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',
 
668
                                               key='good')
 
669
        self.assertEqual(r1['good'], set(['value']))
 
670
        self.assertFalse('fake_key1' in r1)
 
671
        # Delete metadata
 
672
        db.aggregate_metadata_delete(ctxt, a3.id, 'good')
 
673
        r2 = db.aggregate_metadata_get_by_host(ctxt, 'foo.openstack.org',
 
674
                                               key='good')
 
675
        self.assertFalse('good' in r2)
519
676
 
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'))
526
682
 
527
683
    def test_aggregate_delete_raise_not_found(self):
528
684
        """Ensure AggregateNotFound is raised when deleting an aggregate."""
542
698
        self.assertEqual(0, len(expected))
543
699
        aggregate = db.aggregate_get(ctxt.elevated(read_deleted='yes'),
544
700
                                     result['id'])
545
 
        self.assertEqual(aggregate["operational_state"], "dismissed")
 
701
        self.assertEqual(aggregate.deleted, True)
546
702
 
547
703
    def test_aggregate_update(self):
548
704
        """Ensure an aggregate can be updated."""
670
826
        expected = db.aggregate_host_get_all(ctxt, result.id)
671
827
        self.assertEqual(len(expected), 1)
672
828
 
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', },
681
836
                          metadata=None)
 
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)
682
840
 
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)
833
991
 
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)
839
997
 
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)
846
1004
 
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)
854
1012
 
855
1013