~ubuntu-branches/ubuntu/raring/nova/raring-proposed

« back to all changes in this revision

Viewing changes to nova/tests/api/ec2/test_cloud.py

  • Committer: Package Import Robot
  • Author(s): Chuck Short, Adam Gandelman, Chuck Short
  • Date: 2012-11-23 09:04:58 UTC
  • mfrom: (1.1.66)
  • Revision ID: package-import@ubuntu.com-20121123090458-91565o7aev1i1h71
Tags: 2013.1~g1-0ubuntu1
[ Adam Gandelman ]
* debian/control: Ensure novaclient is upgraded with nova,
  require python-keystoneclient >= 1:2.9.0. (LP: #1073289)
* debian/patches/{ubuntu/*, rbd-security.patch}: Dropped, applied
  upstream.
* debian/control: Add python-testtools to Build-Depends.

[ Chuck Short ]
* New upstream version.
* Refreshed debian/patches/avoid_setuptools_git_dependency.patch.
* debian/rules: FTBFS if missing binaries.
* debian/nova-scheudler.install: Add missing rabbit-queues and
  nova-rpc-zmq-receiver.
* Remove nova-volume since it doesnt exist anymore, transition to cinder-*.
* debian/rules: install apport hook in the right place.
* debian/patches/ubuntu-show-tests.patch: Display test failures.
* debian/control: Add depends on genisoimage
* debian/control: Suggest guestmount.
* debian/control: Suggest websockify. (LP: #1076442)
* debian/nova.conf: Disable nova-volume service.
* debian/control: Depend on xen-system-* rather than the hypervisor.
* debian/control, debian/mans/nova-conductor.8, debian/nova-conductor.init,
  debian/nova-conductor.install, debian/nova-conductor.logrotate
  debian/nova-conductor.manpages, debian/nova-conductor.postrm
  debian/nova-conductor.upstart.in: Add nova-conductor service.
* debian/control: Add python-fixtures as a build deps.

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
import datetime
23
23
import functools
24
24
import os
25
 
import shutil
26
25
import string
27
26
import tempfile
28
27
 
36
35
from nova import context
37
36
from nova import db
38
37
from nova import exception
39
 
from nova import flags
40
38
from nova.image import s3
41
39
from nova.network import api as network_api
 
40
from nova.openstack.common import cfg
42
41
from nova.openstack.common import log as logging
43
42
from nova.openstack.common import rpc
44
43
from nova import test
45
44
from nova.tests import fake_network
46
45
from nova.tests.image import fake
 
46
from nova.tests import matchers
47
47
from nova import utils
48
48
from nova.virt import fake as fake_virt
49
 
from nova.volume import iscsi
50
 
 
51
 
 
 
49
from nova import volume
 
50
 
 
51
CONF = cfg.CONF
 
52
CONF.import_opt('default_image', 'nova.config')
 
53
CONF.import_opt('default_instance_type', 'nova.config')
 
54
CONF.import_opt('use_ipv6', 'nova.config')
52
55
LOG = logging.getLogger(__name__)
53
 
FLAGS = flags.FLAGS
54
56
 
55
57
 
56
58
def get_fake_cache():
72
74
                                                  floats=['1.2.3.4',
73
75
                                                          '5.6.7.8']),
74
76
                                              _ip('192.168.0.4')]}]}}]
75
 
    if FLAGS.use_ipv6:
 
77
    if CONF.use_ipv6:
76
78
        ipv6_addr = 'fe80:b33f::a8bb:ccff:fedd:eeff'
77
79
        info[0]['network']['subnets'].append({'cidr': 'fe80:b33f::/64',
78
80
                                              'ips': [_ip(ipv6_addr)]})
95
97
class CloudTestCase(test.TestCase):
96
98
    def setUp(self):
97
99
        super(CloudTestCase, self).setUp()
98
 
        vol_tmpdir = tempfile.mkdtemp()
99
100
        self.flags(compute_driver='nova.virt.fake.FakeDriver',
100
 
                   volumes_dir=vol_tmpdir)
101
 
        self.stubs.Set(iscsi.TgtAdm, '_get_target', self.fake_get_target)
102
 
        self.stubs.Set(iscsi.TgtAdm, 'remove_iscsi_target',
103
 
                       self.fake_remove_iscsi_target)
 
101
                   volume_api_class='nova.tests.fake_volume.API')
104
102
 
105
103
        def fake_show(meh, context, id):
106
104
            return {'id': id,
107
105
                    'name': 'fake_name',
108
106
                    'container_format': 'ami',
 
107
                    'status': 'active',
109
108
                    'properties': {
110
109
                        'kernel_id': 'cedef40a-ed67-4d10-800e-17455edce175',
111
110
                        'ramdisk_id': 'cedef40a-ed67-4d10-800e-17455edce175',
129
128
 
130
129
        # set up our cloud
131
130
        self.cloud = cloud.CloudController()
132
 
        self.flags(compute_scheduler_driver='nova.scheduler.'
133
 
                'chance.ChanceScheduler')
 
131
        self.flags(scheduler_driver='nova.scheduler.chance.ChanceScheduler')
134
132
 
135
133
        # set up services
136
134
        self.compute = self.start_service('compute')
137
135
        self.scheduler = self.start_service('scheduler')
138
136
        self.network = self.start_service('network')
139
 
        self.volume = self.start_service('volume')
140
137
 
141
138
        self.user_id = 'fake'
142
139
        self.project_id = 'fake'
143
140
        self.context = context.RequestContext(self.user_id,
144
141
                                              self.project_id,
145
142
                                              is_admin=True)
 
143
        self.volume_api = volume.API()
146
144
 
147
145
        # NOTE(comstud): Make 'cast' behave like a 'call' which will
148
146
        # ensure that operations complete
155
153
                               '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6')
156
154
 
157
155
    def tearDown(self):
158
 
        try:
159
 
            shutil.rmtree(FLAGS.volumes_dir)
160
 
        except OSError, e:
161
 
            pass
 
156
        self.volume_api.reset_fake_api(self.context)
162
157
        super(CloudTestCase, self).tearDown()
163
158
        fake.FakeImageService_reset()
164
159
 
265
260
                                                 project_id=project_id)
266
261
 
267
262
        fixed_ips = nw_info.fixed_ips()
268
 
        ec2_id = ec2utils.id_to_ec2_inst_id(inst['id'])
 
263
        ec2_id = ec2utils.id_to_ec2_inst_id(inst['uuid'])
269
264
 
270
265
        self.stubs.Set(ec2utils, 'get_ip_info_for_instance',
271
266
                       lambda *args: {'fixed_ips': ['10.0.0.1'],
285
280
        db.instance_destroy(self.context, inst['uuid'])
286
281
        db.floating_ip_destroy(self.context, address)
287
282
 
 
283
    def test_disassociate_auto_assigned_address(self):
 
284
        """Verifies disassociating auto assigned floating IP
 
285
        raises an exception
 
286
        """
 
287
        address = "10.10.10.10"
 
288
 
 
289
        def fake_get(*args, **kwargs):
 
290
            pass
 
291
 
 
292
        def fake_disassociate_floating_ip(*args, **kwargs):
 
293
            raise exception.CannotDisassociateAutoAssignedFloatingIP()
 
294
 
 
295
        self.stubs.Set(network_api.API, 'get_instance_id_by_floating_address',
 
296
                       lambda *args: 1)
 
297
        self.stubs.Set(self.cloud.compute_api, 'get', fake_get)
 
298
        self.stubs.Set(network_api.API, 'disassociate_floating_ip',
 
299
                                    fake_disassociate_floating_ip)
 
300
 
 
301
        self.assertRaises(exception.EC2APIError,
 
302
                          self.cloud.disassociate_address,
 
303
                          self.context, public_ip=address)
 
304
 
288
305
    def test_describe_security_groups(self):
289
306
        """Makes sure describe_security_groups works and filters results."""
290
307
        sec = db.security_group_create(self.context,
365
382
 
366
383
    def test_security_group_quota_limit(self):
367
384
        self.flags(quota_security_groups=10)
368
 
        for i in range(1, FLAGS.quota_security_groups + 1):
 
385
        for i in range(1, CONF.quota_security_groups + 1):
369
386
            name = 'test name %i' % i
370
387
            descript = 'test description %i' % i
371
388
            create = self.cloud.create_security_group
658
675
 
659
676
        self.cloud.delete_security_group(self.context, 'testgrp')
660
677
 
661
 
    def test_describe_volumes(self):
662
 
        """Makes sure describe_volumes works and filters results."""
663
 
        vol1 = db.volume_create(self.context, {'project_id': self.project_id})
664
 
        vol2 = db.volume_create(self.context, {'project_id': self.project_id})
665
 
        result = self.cloud.describe_volumes(self.context)
666
 
        self.assertEqual(len(result['volumeSet']), 2)
667
 
        volume_id = ec2utils.id_to_ec2_vol_id(vol2['id'])
668
 
        result = self.cloud.describe_volumes(self.context,
669
 
                                             volume_id=[volume_id])
670
 
        self.assertEqual(len(result['volumeSet']), 1)
671
 
        self.assertEqual(
672
 
                ec2utils.ec2_vol_id_to_uuid(
673
 
                    result['volumeSet'][0]['volumeId']),
674
 
                vol2['id'])
675
 
        db.volume_destroy(self.context, vol1['id'])
676
 
        db.volume_destroy(self.context, vol2['id'])
677
 
 
678
 
    def test_create_volume_in_availability_zone(self):
679
 
        """Makes sure create_volume works when we specify an availability
680
 
        zone
681
 
        """
682
 
        availability_zone = 'zone1:host1'
683
 
 
684
 
        result = self.cloud.create_volume(self.context,
685
 
                                          size=1,
686
 
                                          availability_zone=availability_zone)
687
 
        volume_id = result['volumeId']
688
 
        availabilityZone = result['availabilityZone']
689
 
        self.assertEqual(availabilityZone, availability_zone)
690
 
        result = self.cloud.describe_volumes(self.context)
691
 
        self.assertEqual(len(result['volumeSet']), 1)
692
 
        self.assertEqual(result['volumeSet'][0]['volumeId'], volume_id)
693
 
        self.assertEqual(result['volumeSet'][0]['availabilityZone'],
694
 
                         availabilityZone)
695
 
 
696
 
        db.volume_destroy(self.context, ec2utils.ec2_vol_id_to_uuid(volume_id))
697
 
 
698
 
    def test_create_volume_from_snapshot(self):
699
 
        """Makes sure create_volume works when we specify a snapshot."""
700
 
        vol = db.volume_create(self.context, {'size': 1,
701
 
                                              'project_id': self.project_id})
702
 
        snap = db.snapshot_create(self.context, {'volume_id': vol['id'],
703
 
                                                 'volume_size': vol['size'],
704
 
                                                 'status': "available"})
705
 
        snapshot_id = ec2utils.id_to_ec2_snap_id(snap['id'])
706
 
 
707
 
        result = self.cloud.create_volume(self.context,
708
 
                                          snapshot_id=snapshot_id)
709
 
        volume_id = result['volumeId']
710
 
        result = self.cloud.describe_volumes(self.context)
711
 
        self.assertEqual(len(result['volumeSet']), 2)
712
 
        self.assertEqual(result['volumeSet'][1]['volumeId'], volume_id)
713
 
 
714
 
        db.volume_destroy(self.context, ec2utils.ec2_vol_id_to_uuid(volume_id))
715
 
        db.snapshot_destroy(self.context, snap['id'])
716
 
        db.volume_destroy(self.context, vol['id'])
717
 
 
718
678
    def test_describe_availability_zones(self):
719
679
        """Makes sure describe_availability_zones works and filters results."""
720
680
        service1 = db.service_create(self.context, {'host': 'host1_zones',
749
709
        result = self.cloud.describe_availability_zones(admin_ctxt,
750
710
                                                        zone_name='verbose')
751
711
 
752
 
        self.assertEqual(len(result['availabilityZoneInfo']), 15)
 
712
        self.assertEqual(len(result['availabilityZoneInfo']), 13)
753
713
        db.service_destroy(self.context, service1['id'])
754
714
        db.service_destroy(self.context, service2['id'])
755
715
 
756
 
    def test_describe_snapshots(self):
757
 
        """Makes sure describe_snapshots works and filters results."""
758
 
        vol = db.volume_create(self.context, {})
759
 
        snap1 = db.snapshot_create(self.context,
760
 
                {'volume_id': vol['id'], 'project_id': self.project_id})
761
 
        snap2 = db.snapshot_create(self.context,
762
 
                {'volume_id': vol['id'], 'project_id': self.project_id})
763
 
        result = self.cloud.describe_snapshots(self.context)
764
 
        self.assertEqual(len(result['snapshotSet']), 2)
765
 
        snapshot_id = ec2utils.id_to_ec2_snap_id(snap2['id'])
766
 
        result = self.cloud.describe_snapshots(self.context,
767
 
                                               snapshot_id=[snapshot_id])
768
 
        self.assertEqual(len(result['snapshotSet']), 1)
769
 
        self.assertEqual(
770
 
            ec2utils.ec2_snap_id_to_uuid(
771
 
                result['snapshotSet'][0]['snapshotId']),
772
 
            snap2['id'])
773
 
        db.snapshot_destroy(self.context, snap1['id'])
774
 
        db.snapshot_destroy(self.context, snap2['id'])
775
 
        db.volume_destroy(self.context, vol['id'])
776
 
 
777
 
    def test_create_snapshot(self):
778
 
        """Makes sure create_snapshot works."""
779
 
        vol = db.volume_create(self.context,
780
 
                {'status': "available", 'size': 0})
781
 
        volume_id = ec2utils.id_to_ec2_vol_id(vol['id'])
782
 
 
783
 
        result = self.cloud.create_snapshot(self.context,
784
 
                                            volume_id=volume_id)
785
 
        snapshot_id = result['snapshotId']
786
 
        result = self.cloud.describe_snapshots(self.context)
787
 
        self.assertEqual(len(result['snapshotSet']), 1)
788
 
        self.assertEqual(result['snapshotSet'][0]['snapshotId'], snapshot_id)
789
 
 
790
 
        db.snapshot_destroy(self.context, ec2utils.ec2_id_to_id(snapshot_id))
791
 
        db.volume_destroy(self.context, vol['id'])
792
 
 
793
 
    def test_delete_snapshot(self):
794
 
        """Makes sure delete_snapshot works."""
795
 
        vol = db.volume_create(self.context,
796
 
                {'status': "available", 'size': 0})
797
 
        snap = db.snapshot_create(self.context,
798
 
                {'volume_id': vol['id'],
799
 
                 'status': "available",
800
 
                 'volume_size': 0})
801
 
        snapshot_id = ec2utils.id_to_ec2_snap_id(snap['id'])
802
 
 
803
 
        result = self.cloud.delete_snapshot(self.context,
804
 
                                            snapshot_id=snapshot_id)
805
 
        self.assertTrue(result)
806
 
 
807
 
        db.volume_destroy(self.context, vol['id'])
808
 
 
809
716
    def test_describe_instances(self):
810
717
        """Makes sure describe_instances works and filters results."""
811
718
        self.flags(use_ipv6=True)
1012
919
        result = self.cloud.describe_instances(self.context)
1013
920
        self.assertEqual(len(result['reservationSet']), 2)
1014
921
 
1015
 
    def _block_device_mapping_create(self, instance_uuid, mappings):
1016
 
        volumes = []
1017
 
        for bdm in mappings:
1018
 
            db.block_device_mapping_create(self.context, bdm)
1019
 
            if 'volume_id' in bdm:
1020
 
                values = {'id': bdm['volume_id']}
1021
 
                for bdm_key, vol_key in [('snapshot_id', 'snapshot_id'),
1022
 
                                         ('snapshot_size', 'volume_size'),
1023
 
                                         ('delete_on_termination',
1024
 
                                          'delete_on_termination')]:
1025
 
                    if bdm_key in bdm:
1026
 
                        values[vol_key] = bdm[bdm_key]
1027
 
                vol = db.volume_create(self.context, values)
1028
 
                db.volume_attached(self.context, vol['id'],
1029
 
                                   instance_uuid, bdm['device_name'])
1030
 
                volumes.append(vol)
1031
 
        return volumes
1032
 
 
1033
 
    def _setUpBlockDeviceMapping(self):
1034
 
        image_uuid = 'cedef40a-ed67-4d10-800e-17455edce175'
1035
 
        inst1 = db.instance_create(self.context,
1036
 
                                  {'image_ref': image_uuid,
1037
 
                                   'instance_type_id': 1,
1038
 
                                   'root_device_name': '/dev/sdb1'})
1039
 
        inst2 = db.instance_create(self.context,
1040
 
                                  {'image_ref': image_uuid,
1041
 
                                   'instance_type_id': 1,
1042
 
                                   'root_device_name': '/dev/sdc1'})
1043
 
 
1044
 
        instance_id = inst1['id']
1045
 
        instance_uuid = inst1['uuid']
1046
 
        mappings0 = [
1047
 
            {'instance_uuid': instance_uuid,
1048
 
             'device_name': '/dev/sdb1',
1049
 
             'snapshot_id': '1',
1050
 
             'volume_id': '2'},
1051
 
            {'instance_uuid': instance_uuid,
1052
 
             'device_name': '/dev/sdb2',
1053
 
             'volume_id': '3',
1054
 
             'volume_size': 1},
1055
 
            {'instance_uuid': instance_uuid,
1056
 
             'device_name': '/dev/sdb3',
1057
 
             'delete_on_termination': True,
1058
 
             'snapshot_id': '4',
1059
 
             'volume_id': '5'},
1060
 
            {'instance_uuid': instance_uuid,
1061
 
             'device_name': '/dev/sdb4',
1062
 
             'delete_on_termination': False,
1063
 
             'snapshot_id': '6',
1064
 
             'volume_id': '7'},
1065
 
            {'instance_uuid': instance_uuid,
1066
 
             'device_name': '/dev/sdb5',
1067
 
             'snapshot_id': '8',
1068
 
             'volume_id': '9',
1069
 
             'volume_size': 0},
1070
 
            {'instance_uuid': instance_uuid,
1071
 
             'device_name': '/dev/sdb6',
1072
 
             'snapshot_id': '10',
1073
 
             'volume_id': '11',
1074
 
             'volume_size': 1},
1075
 
            {'instance_uuid': instance_uuid,
1076
 
             'device_name': '/dev/sdb7',
1077
 
             'no_device': True},
1078
 
            {'instance_uuid': instance_uuid,
1079
 
             'device_name': '/dev/sdb8',
1080
 
             'virtual_name': 'swap'},
1081
 
            {'instance_uuid': instance_uuid,
1082
 
             'device_name': '/dev/sdb9',
1083
 
             'virtual_name': 'ephemeral3'}]
1084
 
 
1085
 
        volumes = self._block_device_mapping_create(instance_uuid, mappings0)
1086
 
        return (inst1, inst2, volumes)
1087
 
 
1088
 
    def _tearDownBlockDeviceMapping(self, inst1, inst2, volumes):
1089
 
        for vol in volumes:
1090
 
            db.volume_destroy(self.context, vol['id'])
1091
 
        for uuid in (inst1['uuid'], inst2['uuid']):
1092
 
            for bdm in db.block_device_mapping_get_all_by_instance(
1093
 
                self.context, uuid):
1094
 
                db.block_device_mapping_destroy(self.context, bdm['id'])
1095
 
        db.instance_destroy(self.context, inst2['uuid'])
1096
 
        db.instance_destroy(self.context, inst1['uuid'])
1097
 
 
1098
 
    _expected_instance_bdm1 = {
1099
 
        'instanceId': 'i-00000001',
1100
 
        'rootDeviceName': '/dev/sdb1',
1101
 
        'rootDeviceType': 'ebs'}
1102
 
 
1103
 
    _expected_block_device_mapping0 = [
1104
 
        {'deviceName': '/dev/sdb1',
1105
 
         'ebs': {'status': 'in-use',
1106
 
                 'deleteOnTermination': False,
1107
 
                 'volumeId': '2',
1108
 
                 }},
1109
 
        {'deviceName': '/dev/sdb2',
1110
 
         'ebs': {'status': 'in-use',
1111
 
                 'deleteOnTermination': False,
1112
 
                 'volumeId': '3',
1113
 
                 }},
1114
 
        {'deviceName': '/dev/sdb3',
1115
 
         'ebs': {'status': 'in-use',
1116
 
                 'deleteOnTermination': True,
1117
 
                 'volumeId': '5',
1118
 
                 }},
1119
 
        {'deviceName': '/dev/sdb4',
1120
 
         'ebs': {'status': 'in-use',
1121
 
                 'deleteOnTermination': False,
1122
 
                 'volumeId': '7',
1123
 
                 }},
1124
 
        {'deviceName': '/dev/sdb5',
1125
 
         'ebs': {'status': 'in-use',
1126
 
                 'deleteOnTermination': False,
1127
 
                 'volumeId': '9',
1128
 
                 }},
1129
 
        {'deviceName': '/dev/sdb6',
1130
 
         'ebs': {'status': 'in-use',
1131
 
                 'deleteOnTermination': False,
1132
 
                 'volumeId': '11', }}]
1133
 
        # NOTE(yamahata): swap/ephemeral device case isn't supported yet.
1134
 
 
1135
 
    _expected_instance_bdm2 = {
1136
 
        'instanceId': 'i-00000002',
1137
 
        'rootDeviceName': '/dev/sdc1',
1138
 
        'rootDeviceType': 'instance-store'}
1139
 
 
1140
 
    def test_format_instance_bdm(self):
1141
 
        (inst1, inst2, volumes) = self._setUpBlockDeviceMapping()
1142
 
 
1143
 
        result = {}
1144
 
        self.cloud._format_instance_bdm(self.context, inst1['uuid'],
1145
 
                                        '/dev/sdb1', result)
1146
 
        self.assertSubDictMatch(
1147
 
            {'rootDeviceType': self._expected_instance_bdm1['rootDeviceType']},
1148
 
            result)
1149
 
        self._assertEqualBlockDeviceMapping(
1150
 
            self._expected_block_device_mapping0, result['blockDeviceMapping'])
1151
 
 
1152
 
        result = {}
1153
 
        self.cloud._format_instance_bdm(self.context, inst2['uuid'],
1154
 
                                        '/dev/sdc1', result)
1155
 
        self.assertSubDictMatch(
1156
 
            {'rootDeviceType': self._expected_instance_bdm2['rootDeviceType']},
1157
 
            result)
1158
 
 
1159
 
        self._tearDownBlockDeviceMapping(inst1, inst2, volumes)
1160
 
 
1161
 
    def _assertInstance(self, instance_id):
1162
 
        ec2_instance_id = ec2utils.id_to_ec2_inst_id(instance_id)
1163
 
        result = self.cloud.describe_instances(self.context,
1164
 
                                               instance_id=[ec2_instance_id])
1165
 
        result = result['reservationSet'][0]
1166
 
        self.assertEqual(len(result['instancesSet']), 1)
1167
 
        result = result['instancesSet'][0]
1168
 
        self.assertEqual(result['instanceId'], ec2_instance_id)
1169
 
        return result
1170
 
 
1171
 
    def _assertEqualBlockDeviceMapping(self, expected, result):
1172
 
        self.assertEqual(len(expected), len(result))
1173
 
        for x in expected:
1174
 
            found = False
1175
 
            for y in result:
1176
 
                if x['deviceName'] == y['deviceName']:
1177
 
                    self.assertSubDictMatch(x, y)
1178
 
                    found = True
1179
 
                    break
1180
 
            self.assertTrue(found)
1181
 
 
1182
 
    def test_describe_instances_bdm(self):
1183
 
        """Make sure describe_instances works with root_device_name and
1184
 
        block device mappings
1185
 
        """
1186
 
        (inst1, inst2, volumes) = self._setUpBlockDeviceMapping()
1187
 
 
1188
 
        result = self._assertInstance(inst1['uuid'])
1189
 
        self.assertSubDictMatch(self._expected_instance_bdm1, result)
1190
 
        self._assertEqualBlockDeviceMapping(
1191
 
            self._expected_block_device_mapping0, result['blockDeviceMapping'])
1192
 
 
1193
 
        result = self._assertInstance(inst2['uuid'])
1194
 
        self.assertSubDictMatch(self._expected_instance_bdm2, result)
1195
 
 
1196
 
        self._tearDownBlockDeviceMapping(inst1, inst2, volumes)
1197
 
 
1198
922
    def test_describe_images(self):
1199
923
        describe_images = self.cloud.describe_images
1200
924
 
1202
926
            return [{'id': 'cedef40a-ed67-4d10-800e-17455edce175',
1203
927
                     'name': 'fake_name',
1204
928
                     'container_format': 'ami',
 
929
                     'status': 'active',
1205
930
                     'properties': {
1206
931
                        'kernel_id': 'cedef40a-ed67-4d10-800e-17455edce175',
1207
932
                        'ramdisk_id': 'cedef40a-ed67-4d10-800e-17455edce175',
1239
964
            for d2 in L2:
1240
965
                self.assertTrue(key in d2)
1241
966
                if d1[key] == d2[key]:
1242
 
                    self.assertDictMatch(d1, d2)
 
967
                    self.assertThat(d1, matchers.DictMatches(d2))
1243
968
 
1244
969
    def _setUpImageSet(self, create_volumes_and_snapshots=False):
1245
970
        mappings1 = [
1257
982
            {'device': 'sdc3', 'virtual': 'swap'},
1258
983
            {'device': 'sdc4', 'virtual': 'swap'}]
1259
984
        block_device_mapping1 = [
1260
 
            {'device_name': '/dev/sdb1', 'snapshot_id': 01234567},
1261
 
            {'device_name': '/dev/sdb2', 'volume_id': 01234567},
 
985
            {'device_name': '/dev/sdb1',
 
986
             'snapshot_id': 'ccec42a2-c220-4806-b762-6b12fbb592e3'},
 
987
            {'device_name': '/dev/sdb2',
 
988
             'volume_id': 'ccec42a2-c220-4806-b762-6b12fbb592e4'},
1262
989
            {'device_name': '/dev/sdb3', 'virtual_name': 'ephemeral5'},
1263
990
            {'device_name': '/dev/sdb4', 'no_device': True},
1264
991
 
1265
 
            {'device_name': '/dev/sdc1', 'snapshot_id': 12345678},
1266
 
            {'device_name': '/dev/sdc2', 'volume_id': 12345678},
 
992
            {'device_name': '/dev/sdc1',
 
993
             'snapshot_id': 'ccec42a2-c220-4806-b762-6b12fbb592e5'},
 
994
            {'device_name': '/dev/sdc2',
 
995
             'volume_id': 'ccec42a2-c220-4806-b762-6b12fbb592e6'},
1267
996
            {'device_name': '/dev/sdc3', 'virtual_name': 'ephemeral6'},
1268
997
            {'device_name': '/dev/sdc4', 'no_device': True}]
1269
998
        image1 = {
1270
999
            'id': 'cedef40a-ed67-4d10-800e-17455edce175',
1271
1000
            'name': 'fake_name',
 
1001
            'status': 'active',
1272
1002
            'properties': {
1273
1003
                'kernel_id': 'cedef40a-ed67-4d10-800e-17455edce175',
1274
1004
                'type': 'machine',
1280
1010
 
1281
1011
        mappings2 = [{'device': '/dev/sda1', 'virtual': 'root'}]
1282
1012
        block_device_mapping2 = [{'device_name': '/dev/sdb1',
1283
 
                                  'snapshot_id': 01234567}]
 
1013
                'snapshot_id': 'ccec42a2-c220-4806-b762-6b12fbb592e7'}]
1284
1014
        image2 = {
1285
1015
            'id': '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6',
1286
1016
            'name': 'fake_name',
 
1017
            'status': 'active',
1287
1018
            'properties': {
1288
1019
                'kernel_id': '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6',
1289
1020
                'type': 'machine',
1312
1043
                    vol = self._volume_create(bdm['volume_id'])
1313
1044
                    volumes.append(vol['id'])
1314
1045
                if 'snapshot_id' in bdm:
1315
 
                    snap = db.snapshot_create(self.context,
1316
 
                                              {'id': bdm['snapshot_id'],
1317
 
                                               'volume_id': 01234567,
1318
 
                                               'status': "available",
1319
 
                                               'volume_size': 1})
 
1046
                    snap = self._snapshot_create(bdm['snapshot_id'])
1320
1047
                    snapshots.append(snap['id'])
1321
1048
        return (volumes, snapshots)
1322
1049
 
1338
1065
    _expected_bdms1 = [
1339
1066
        {'deviceName': '/dev/sdb0', 'virtualName': 'ephemeral0'},
1340
1067
        {'deviceName': '/dev/sdb1', 'ebs': {'snapshotId':
1341
 
                                            'snap-00053977'}},
 
1068
                                            'snap-00000001'}},
1342
1069
        {'deviceName': '/dev/sdb2', 'ebs': {'snapshotId':
1343
 
                                            'vol-00053977'}},
 
1070
                                            'vol-00000001'}},
1344
1071
        {'deviceName': '/dev/sdb3', 'virtualName': 'ephemeral5'},
1345
1072
        # {'deviceName': '/dev/sdb4', 'noDevice': True},
1346
1073
 
1347
1074
        {'deviceName': '/dev/sdc0', 'virtualName': 'swap'},
1348
1075
        {'deviceName': '/dev/sdc1', 'ebs': {'snapshotId':
1349
 
                                            'snap-00bc614e'}},
 
1076
                                            'snap-00000002'}},
1350
1077
        {'deviceName': '/dev/sdc2', 'ebs': {'snapshotId':
1351
 
                                            'vol-00bc614e'}},
 
1078
                                            'vol-00000002'}},
1352
1079
        {'deviceName': '/dev/sdc3', 'virtualName': 'ephemeral6'},
1353
1080
        # {'deviceName': '/dev/sdc4', 'noDevice': True}
1354
1081
        ]
1355
1082
 
1356
1083
    _expected_root_device_name2 = '/dev/sdb1'
1357
1084
    _expected_bdms2 = [{'deviceName': '/dev/sdb1',
1358
 
                       'ebs': {'snapshotId': 'snap-00053977'}}]
 
1085
                       'ebs': {'snapshotId': 'snap-00000003'}}]
1359
1086
 
1360
1087
    # NOTE(yamahata):
1361
1088
    # InstanceBlockDeviceMappingItemType
1394
1121
        def fake_show(meh, context, id):
1395
1122
            return {'id': 'cedef40a-ed67-4d10-800e-17455edce175',
1396
1123
                    'name': 'fake_name',
 
1124
                    'status': 'active',
1397
1125
                    'properties': {
1398
1126
                        'kernel_id': 'cedef40a-ed67-4d10-800e-17455edce175',
1399
1127
                        'ramdisk_id': 'cedef40a-ed67-4d10-800e-17455edce175',
1451
1179
            'id': 'cedef40a-ed67-4d10-800e-17455edce175',
1452
1180
            'name': 'fake_name',
1453
1181
            'container_format': 'ami',
 
1182
            'status': 'active',
1454
1183
            'properties': {
1455
1184
                'kernel_id': 'cedef40a-ed67-4d10-800e-17455edce175',
1456
1185
                'ramdisk_id': 'cedef40a-ed67-4d10-800e-17455edce175',
1490
1219
            # NOTE(vish): We are mocking s3 so make sure we have converted
1491
1220
            #             to ids instead of uuids.
1492
1221
            return {'id': 1,
1493
 
            'name': 'fake_name',
1494
 
            'container_format': 'ami',
1495
 
            'properties': {
1496
 
                'kernel_id': 1,
1497
 
                'ramdisk_id': 1,
1498
 
                'type': 'machine'},
1499
 
            'is_public': False}
 
1222
                    'name': 'fake_name',
 
1223
                    'container_format': 'ami',
 
1224
                    'properties': {'kernel_id': 1,
 
1225
                                   'ramdisk_id': 1,
 
1226
                                   'type': 'machine'
 
1227
                                   },
 
1228
                    'is_public': False
 
1229
                    }
1500
1230
 
1501
1231
        self.stubs.Set(s3.S3ImageService, 'create', fake_create)
1502
1232
        image_location = 'fake_bucket/fake.img.manifest.xml'
1554
1284
                    'imageType': 'machine',
1555
1285
                    'description': None}
1556
1286
        result = self.cloud._format_image(image)
1557
 
        self.assertDictMatch(result, expected)
 
1287
        self.assertThat(result, matchers.DictMatches(expected))
1558
1288
        image['properties']['image_location'] = None
1559
1289
        expected['imageLocation'] = 'None (name)'
1560
1290
        result = self.cloud._format_image(image)
1561
 
        self.assertDictMatch(result, expected)
 
1291
        self.assertThat(result, matchers.DictMatches(expected))
1562
1292
        image['name'] = None
1563
1293
        image['properties']['image_location'] = 'location'
1564
1294
        expected['imageLocation'] = 'location'
1565
1295
        expected['name'] = 'location'
1566
1296
        result = self.cloud._format_image(image)
1567
 
        self.assertDictMatch(result, expected)
 
1297
        self.assertThat(result, matchers.DictMatches(expected))
1568
1298
 
1569
1299
    def test_deregister_image(self):
1570
1300
        deregister_image = self.cloud.deregister_image
1604
1334
    def test_console_output(self):
1605
1335
        instance_id = self._run_instance(
1606
1336
            image_id='ami-1',
1607
 
            instance_type=FLAGS.default_instance_type,
 
1337
            instance_type=CONF.default_instance_type,
1608
1338
            max_count=1)
1609
1339
        output = self.cloud.get_console_output(context=self.context,
1610
1340
                                               instance_id=[instance_id])
1717
1447
 
1718
1448
    def test_run_instances(self):
1719
1449
        kwargs = {'image_id': 'ami-00000001',
1720
 
                  'instance_type': FLAGS.default_instance_type,
 
1450
                  'instance_type': CONF.default_instance_type,
1721
1451
                  'max_count': 1}
1722
1452
        run_instances = self.cloud.run_instances
1723
1453
 
1749
1479
 
1750
1480
    def test_run_instances_availability_zone(self):
1751
1481
        kwargs = {'image_id': 'ami-00000001',
1752
 
                  'instance_type': FLAGS.default_instance_type,
 
1482
                  'instance_type': CONF.default_instance_type,
1753
1483
                  'max_count': 1,
1754
1484
                  'placement': {'availability_zone': 'fake'},
1755
1485
                 }
1785
1515
 
1786
1516
    def test_run_instances_image_state_none(self):
1787
1517
        kwargs = {'image_id': 'ami-00000001',
1788
 
                  'instance_type': FLAGS.default_instance_type,
 
1518
                  'instance_type': CONF.default_instance_type,
1789
1519
                  'max_count': 1}
1790
1520
        run_instances = self.cloud.run_instances
1791
1521
 
1804
1534
 
1805
1535
    def test_run_instances_image_state_invalid(self):
1806
1536
        kwargs = {'image_id': 'ami-00000001',
1807
 
                  'instance_type': FLAGS.default_instance_type,
 
1537
                  'instance_type': CONF.default_instance_type,
1808
1538
                  'max_count': 1}
1809
1539
        run_instances = self.cloud.run_instances
1810
1540
 
1812
1542
            return {'id': 'cedef40a-ed67-4d10-800e-17455edce175',
1813
1543
                    'name': 'fake_name',
1814
1544
                    'container_format': 'ami',
 
1545
                    'status': 'active',
1815
1546
                    'properties': {
1816
1547
                        'kernel_id': 'cedef40a-ed67-4d10-800e-17455edce175',
1817
1548
                        'ramdisk_id': 'cedef40a-ed67-4d10-800e-17455edce175',
1823
1554
                          self.context, **kwargs)
1824
1555
 
1825
1556
    def test_run_instances_image_status_active(self):
1826
 
        kwargs = {'image_id': FLAGS.default_image,
1827
 
                  'instance_type': FLAGS.default_instance_type,
 
1557
        kwargs = {'image_id': CONF.default_image,
 
1558
                  'instance_type': CONF.default_instance_type,
1828
1559
                  'max_count': 1}
1829
1560
        run_instances = self.cloud.run_instances
1830
1561
 
1832
1563
            return {'id': 'cedef40a-ed67-4d10-800e-17455edce175',
1833
1564
                    'name': 'fake_name',
1834
1565
                    'container_format': 'ami',
 
1566
                    'status': 'active',
1835
1567
                    'properties': {
1836
1568
                        'kernel_id': 'cedef40a-ed67-4d10-800e-17455edce175',
1837
1569
                        'ramdisk_id': 'cedef40a-ed67-4d10-800e-17455edce175',
1862
1594
        self._restart_compute_service(periodic_interval=0.3)
1863
1595
 
1864
1596
        kwargs = {'image_id': 'ami-1',
1865
 
                  'instance_type': FLAGS.default_instance_type,
 
1597
                  'instance_type': CONF.default_instance_type,
1866
1598
                  'max_count': 1, }
1867
1599
        instance_id = self._run_instance(**kwargs)
1868
1600
 
1891
1623
 
1892
1624
    def test_start_instances(self):
1893
1625
        kwargs = {'image_id': 'ami-1',
1894
 
                  'instance_type': FLAGS.default_instance_type,
 
1626
                  'instance_type': CONF.default_instance_type,
1895
1627
                  'max_count': 1, }
1896
1628
        instance_id = self._run_instance(**kwargs)
1897
1629
 
1913
1645
 
1914
1646
    def test_stop_instances(self):
1915
1647
        kwargs = {'image_id': 'ami-1',
1916
 
                  'instance_type': FLAGS.default_instance_type,
 
1648
                  'instance_type': CONF.default_instance_type,
1917
1649
                  'max_count': 1, }
1918
1650
        instance_id = self._run_instance(**kwargs)
1919
1651
 
1932
1664
 
1933
1665
    def test_terminate_instances(self):
1934
1666
        kwargs = {'image_id': 'ami-1',
1935
 
                  'instance_type': FLAGS.default_instance_type,
 
1667
                  'instance_type': CONF.default_instance_type,
1936
1668
                  'max_count': 1, }
1937
1669
        instance_id = self._run_instance(**kwargs)
1938
1670
 
1953
1685
 
1954
1686
    def test_terminate_instances_invalid_instance_id(self):
1955
1687
        kwargs = {'image_id': 'ami-1',
1956
 
                  'instance_type': FLAGS.default_instance_type,
 
1688
                  'instance_type': CONF.default_instance_type,
1957
1689
                  'max_count': 1, }
1958
1690
        instance_id = self._run_instance(**kwargs)
1959
1691
 
1964
1696
 
1965
1697
    def test_terminate_instances_disable_terminate(self):
1966
1698
        kwargs = {'image_id': 'ami-1',
1967
 
                  'instance_type': FLAGS.default_instance_type,
 
1699
                  'instance_type': CONF.default_instance_type,
1968
1700
                  'max_count': 1, }
1969
1701
        instance_id = self._run_instance(**kwargs)
1970
1702
 
1997
1729
 
1998
1730
    def test_terminate_instances_two_instances(self):
1999
1731
        kwargs = {'image_id': 'ami-1',
2000
 
                  'instance_type': FLAGS.default_instance_type,
 
1732
                  'instance_type': CONF.default_instance_type,
2001
1733
                  'max_count': 1, }
2002
1734
        inst1 = self._run_instance(**kwargs)
2003
1735
        inst2 = self._run_instance(**kwargs)
2022
1754
 
2023
1755
    def test_reboot_instances(self):
2024
1756
        kwargs = {'image_id': 'ami-1',
2025
 
                  'instance_type': FLAGS.default_instance_type,
 
1757
                  'instance_type': CONF.default_instance_type,
2026
1758
                  'max_count': 1, }
2027
1759
        instance_id = self._run_instance(**kwargs)
2028
1760
 
2035
1767
        self.assertTrue(result)
2036
1768
 
2037
1769
    def _volume_create(self, volume_id=None):
2038
 
        location = '10.0.2.15:3260'
2039
 
        iqn = 'iqn.2010-10.org.openstack:%s' % volume_id
2040
 
        kwargs = {'status': 'available',
2041
 
                  'host': self.volume.host,
 
1770
        kwargs = {'name': 'test-volume',
 
1771
                  'description': 'test volume description',
 
1772
                  'status': 'available',
 
1773
                  'host': 'fake',
2042
1774
                  'size': 1,
2043
 
                  'provider_location': '1 %s,fake %s' % (location, iqn),
2044
 
                  'attach_status': 'detached', }
 
1775
                  'attach_status': 'detached'}
2045
1776
        if volume_id:
2046
 
            kwargs['id'] = volume_id
2047
 
        return db.volume_create(self.context, kwargs)
2048
 
 
2049
 
    def _assert_volume_attached(self, vol, instance_uuid, mountpoint):
2050
 
        self.assertEqual(vol['instance_uuid'], instance_uuid)
2051
 
        self.assertEqual(vol['mountpoint'], mountpoint)
2052
 
        self.assertEqual(vol['status'], "in-use")
2053
 
        self.assertEqual(vol['attach_status'], "attached")
2054
 
 
2055
 
    def _assert_volume_detached(self, vol):
2056
 
        self.assertEqual(vol['instance_uuid'], None)
2057
 
        self.assertEqual(vol['mountpoint'], None)
2058
 
        self.assertEqual(vol['status'], "available")
2059
 
        self.assertEqual(vol['attach_status'], "detached")
2060
 
 
2061
 
    def test_stop_start_with_volume(self):
2062
 
        """Make sure run instance with block device mapping works"""
2063
 
 
2064
 
        # enforce periodic tasks run in short time to avoid wait for 60s.
2065
 
        self._restart_compute_service(periodic_interval=0.3)
2066
 
 
2067
 
        vol1 = self._volume_create()
2068
 
        vol2 = self._volume_create()
2069
 
        kwargs = {'image_id': 'ami-1',
2070
 
                  'instance_type': FLAGS.default_instance_type,
2071
 
                  'max_count': 1,
2072
 
                  'block_device_mapping': [{'device_name': '/dev/vdb',
2073
 
                                            'volume_id': vol1['id'],
2074
 
                                            'delete_on_termination': False},
2075
 
                                           {'device_name': '/dev/vdc',
2076
 
                                            'volume_id': vol2['id'],
2077
 
                                            'delete_on_termination': True},
2078
 
                                           ]}
2079
 
        ec2_instance_id = self._run_instance(**kwargs)
2080
 
        instance_uuid = ec2utils.ec2_instance_id_to_uuid(self.context,
2081
 
                                                         ec2_instance_id)
2082
 
        instance_id = ec2utils.ec2_id_to_id(ec2_instance_id)
2083
 
 
2084
 
        vols = db.volume_get_all_by_instance_uuid(self.context, instance_uuid)
2085
 
        self.assertEqual(len(vols), 2)
2086
 
        for vol in vols:
2087
 
            self.assertTrue(vol['id'] == vol1['id'] or vol['id'] == vol2['id'])
2088
 
 
2089
 
        vol = db.volume_get(self.context, vol1['id'])
2090
 
        self._assert_volume_attached(vol, instance_uuid, '/dev/vdb')
2091
 
 
2092
 
        vol = db.volume_get(self.context, vol2['id'])
2093
 
        self._assert_volume_attached(vol, instance_uuid, '/dev/vdc')
2094
 
 
2095
 
        result = self.cloud.stop_instances(self.context, [ec2_instance_id])
2096
 
        self.assertTrue(result)
2097
 
 
2098
 
        vol = db.volume_get(self.context, vol1['id'])
2099
 
        self._assert_volume_attached(vol, instance_uuid, '/dev/vdb')
2100
 
 
2101
 
        vol = db.volume_get(self.context, vol2['id'])
2102
 
        self._assert_volume_attached(vol, instance_uuid, '/dev/vdc')
2103
 
 
2104
 
        self.cloud.start_instances(self.context, [ec2_instance_id])
2105
 
        vols = db.volume_get_all_by_instance_uuid(self.context, instance_uuid)
2106
 
        self.assertEqual(len(vols), 2)
2107
 
        for vol in vols:
2108
 
            self.assertTrue(vol['id'] == vol1['id'] or vol['id'] == vol2['id'])
2109
 
            self.assertTrue(vol['mountpoint'] == '/dev/vdb' or
2110
 
                            vol['mountpoint'] == '/dev/vdc')
2111
 
            self.assertEqual(vol['instance_uuid'], instance_uuid)
2112
 
            self.assertEqual(vol['status'], "in-use")
2113
 
            self.assertEqual(vol['attach_status'], "attached")
2114
 
 
2115
 
        self.cloud.terminate_instances(self.context, [ec2_instance_id])
2116
 
 
2117
 
        admin_ctxt = context.get_admin_context(read_deleted="no")
2118
 
        vol = db.volume_get(admin_ctxt, vol1['id'])
2119
 
        self.assertFalse(vol['deleted'])
2120
 
        db.volume_destroy(self.context, vol1['id'])
2121
 
 
2122
 
        admin_ctxt = context.get_admin_context(read_deleted="only")
2123
 
        vol = db.volume_get(admin_ctxt, vol2['id'])
2124
 
        self.assertTrue(vol['deleted'])
2125
 
 
2126
 
        self._restart_compute_service()
2127
 
 
2128
 
    def test_stop_with_attached_volume(self):
2129
 
        """Make sure attach info is reflected to block device mapping"""
2130
 
        # enforce periodic tasks run in short time to avoid wait for 60s.
2131
 
        self._restart_compute_service(periodic_interval=0.3)
2132
 
 
2133
 
        vol1 = self._volume_create()
2134
 
        vol2 = self._volume_create()
2135
 
        kwargs = {'image_id': 'ami-1',
2136
 
                  'instance_type': FLAGS.default_instance_type,
2137
 
                  'max_count': 1,
2138
 
                  'block_device_mapping': [{'device_name': '/dev/sdb',
2139
 
                                            'volume_id': vol1['id'],
2140
 
                                            'delete_on_termination': True}]}
2141
 
        ec2_instance_id = self._run_instance(**kwargs)
2142
 
        instance_id = ec2utils.ec2_id_to_id(ec2_instance_id)
2143
 
        instance_uuid = ec2utils.ec2_instance_id_to_uuid(self.context,
2144
 
                                                         ec2_instance_id)
2145
 
 
2146
 
        vols = db.volume_get_all_by_instance_uuid(self.context, instance_uuid)
2147
 
        self.assertEqual(len(vols), 1)
2148
 
        for vol in vols:
2149
 
            self.assertEqual(vol['id'], vol1['id'])
2150
 
            self._assert_volume_attached(vol, instance_uuid, '/dev/sdb')
2151
 
 
2152
 
        vol = db.volume_get(self.context, vol2['id'])
2153
 
        self._assert_volume_detached(vol)
2154
 
 
2155
 
        instance = db.instance_get(self.context, instance_id)
2156
 
        self.cloud.compute_api.attach_volume(self.context,
2157
 
                                             instance,
2158
 
                                             volume_id=vol2['id'],
2159
 
                                             device='/dev/vdc')
2160
 
        vol = db.volume_get(self.context, vol2['id'])
2161
 
        self._assert_volume_attached(vol, instance_uuid, '/dev/sdc')
2162
 
 
2163
 
        self.cloud.compute_api.detach_volume(self.context,
2164
 
                                             volume_id=vol1['id'])
2165
 
        vol = db.volume_get(self.context, vol1['id'])
2166
 
        self._assert_volume_detached(vol)
2167
 
 
2168
 
        result = self.cloud.stop_instances(self.context, [ec2_instance_id])
2169
 
        self.assertTrue(result)
2170
 
 
2171
 
        vol = db.volume_get(self.context, vol2['id'])
2172
 
        self._assert_volume_attached(vol, instance_uuid, '/dev/sdc')
2173
 
 
2174
 
        self.cloud.start_instances(self.context, [ec2_instance_id])
2175
 
        vols = db.volume_get_all_by_instance_uuid(self.context, instance_uuid)
2176
 
        self.assertEqual(len(vols), 1)
2177
 
        for vol in vols:
2178
 
            self.assertEqual(vol['id'], vol2['id'])
2179
 
            self._assert_volume_attached(vol, instance_uuid, '/dev/sdc')
2180
 
 
2181
 
        vol = db.volume_get(self.context, vol1['id'])
2182
 
        self._assert_volume_detached(vol)
2183
 
 
2184
 
        self.cloud.terminate_instances(self.context, [ec2_instance_id])
2185
 
 
2186
 
        for vol_id in (vol1['id'], vol2['id']):
2187
 
            vol = db.volume_get(self.context, vol_id)
2188
 
            self.assertEqual(vol['id'], vol_id)
2189
 
            self._assert_volume_detached(vol)
2190
 
            db.volume_destroy(self.context, vol_id)
2191
 
 
2192
 
        self._restart_compute_service()
 
1777
            kwargs['volume_id'] = volume_id
 
1778
        return self.volume_api.create_with_kwargs(self.context, **kwargs)
 
1779
 
 
1780
    def _snapshot_create(self, snapshot_id=None):
 
1781
        kwargs = {'volume_id': 'ccec42a2-c220-4806-b762-6b12fbb592e4',
 
1782
                  'status': "available",
 
1783
                  'volume_size': 1}
 
1784
        if snapshot_id:
 
1785
            kwargs['snap_id'] = snapshot_id
 
1786
        return self.volume_api.create_snapshot_with_kwargs(self.context,
 
1787
                                                           **kwargs)
2193
1788
 
2194
1789
    def _create_snapshot(self, ec2_volume_id):
2195
1790
        result = self.cloud.create_snapshot(self.context,
2196
1791
                                            volume_id=ec2_volume_id)
2197
1792
        return result['snapshotId']
2198
1793
 
2199
 
    def test_run_with_snapshot(self):
2200
 
        """Makes sure run/stop/start instance with snapshot works."""
2201
 
        vol = self._volume_create()
2202
 
        ec2_volume_id = ec2utils.id_to_ec2_vol_id(vol['id'])
2203
 
 
2204
 
        ec2_snapshot1_id = self._create_snapshot(ec2_volume_id)
2205
 
        snapshot1_id = ec2utils.ec2_snap_id_to_uuid(ec2_snapshot1_id)
2206
 
        ec2_snapshot2_id = self._create_snapshot(ec2_volume_id)
2207
 
        snapshot2_id = ec2utils.ec2_snap_id_to_uuid(ec2_snapshot2_id)
2208
 
 
2209
 
        kwargs = {'image_id': 'ami-1',
2210
 
                  'instance_type': FLAGS.default_instance_type,
2211
 
                  'max_count': 1,
2212
 
                  'block_device_mapping': [{'device_name': '/dev/vdb',
2213
 
                                            'snapshot_id': snapshot1_id,
2214
 
                                            'delete_on_termination': False, },
2215
 
                                           {'device_name': '/dev/vdc',
2216
 
                                            'snapshot_id': snapshot2_id,
2217
 
                                            'delete_on_termination': True}]}
2218
 
        ec2_instance_id = self._run_instance(**kwargs)
2219
 
        instance_id = ec2utils.ec2_vol_id_to_uuid(ec2_instance_id)
2220
 
        instance_uuid = ec2utils.ec2_instance_id_to_uuid(self.context,
2221
 
                                                         ec2_instance_id)
2222
 
 
2223
 
        vols = db.volume_get_all_by_instance_uuid(self.context, instance_uuid)
2224
 
        self.assertEqual(len(vols), 2)
2225
 
        vol1_id = None
2226
 
        vol2_id = None
2227
 
        for vol in vols:
2228
 
            snapshot_id = vol['snapshot_id']
2229
 
            if snapshot_id == snapshot1_id:
2230
 
                vol1_id = vol['id']
2231
 
                mountpoint = '/dev/vdb'
2232
 
            elif snapshot_id == snapshot2_id:
2233
 
                vol2_id = vol['id']
2234
 
                mountpoint = '/dev/vdc'
2235
 
            else:
2236
 
                self.fail()
2237
 
 
2238
 
            self._assert_volume_attached(vol, instance_uuid, mountpoint)
2239
 
 
2240
 
        self.assertTrue(vol1_id)
2241
 
        self.assertTrue(vol2_id)
2242
 
 
2243
 
        self.cloud.terminate_instances(self.context, [ec2_instance_id])
2244
 
 
2245
 
        admin_ctxt = context.get_admin_context(read_deleted="no")
2246
 
        vol = db.volume_get(admin_ctxt, vol1_id)
2247
 
        self._assert_volume_detached(vol)
2248
 
        self.assertFalse(vol['deleted'])
2249
 
        db.volume_destroy(self.context, vol1_id)
2250
 
 
2251
 
        admin_ctxt = context.get_admin_context(read_deleted="only")
2252
 
        vol = db.volume_get(admin_ctxt, vol2_id)
2253
 
        self.assertTrue(vol['deleted'])
2254
 
 
2255
 
        for snapshot_id in (ec2_snapshot1_id, ec2_snapshot2_id):
2256
 
            self.cloud.delete_snapshot(self.context, snapshot_id)
2257
 
 
2258
1794
    def _do_test_create_image(self, no_reboot):
2259
1795
        """Make sure that CreateImage works"""
2260
1796
        # enforce periodic tasks run in short time to avoid wait for 60s.
2264
1800
            create_volumes_and_snapshots=True)
2265
1801
 
2266
1802
        kwargs = {'image_id': 'ami-1',
2267
 
                  'instance_type': FLAGS.default_instance_type,
 
1803
                  'instance_type': CONF.default_instance_type,
2268
1804
                  'max_count': 1}
2269
1805
        ec2_instance_id = self._run_instance(**kwargs)
2270
1806
 
2289
1825
            class BDM(object):
2290
1826
                def __init__(self):
2291
1827
                    self.no_device = None
2292
 
                    self.values = dict(snapshot_id=snapshots[0],
 
1828
                    self.values = dict(id=1,
 
1829
                                       snapshot_id=snapshots[0],
2293
1830
                                       volume_id=volumes[0],
2294
1831
                                       virtual_name=None,
2295
1832
                                       volume_size=1,
2296
1833
                                       device_name='sda1',
2297
 
                                       delete_on_termination=False)
 
1834
                                       delete_on_termination=False,
 
1835
                                       connection_info='{"foo":"bar"}')
2298
1836
 
2299
1837
                def __getattr__(self, name):
2300
 
                    return self.values.get(name)
 
1838
                    """Properly delegate dotted lookups"""
 
1839
                    if name in self.__dict__['values']:
 
1840
                        return self.values.get(name)
 
1841
                    try:
 
1842
                        return self.__dict__[name]
 
1843
                    except KeyError:
 
1844
                        raise AttributeError
2301
1845
 
2302
1846
                def __getitem__(self, key):
2303
1847
                    return self.values.get(key)
2304
1848
 
 
1849
                def iteritems(self):
 
1850
                    return self.values.iteritems()
 
1851
 
2305
1852
            return [BDM()]
2306
1853
 
2307
1854
        self.stubs.Set(db, 'block_device_mapping_get_all_by_instance',
2330
1877
        self.assertEquals(bdm.get('deviceName'), 'sda1')
2331
1878
        self.assertTrue('ebs' in bdm)
2332
1879
        self.assertEquals(bdm['ebs'].get('snapshotId'),
2333
 
                          'snap-%08x' % snapshots[0])
 
1880
                          ec2utils.id_to_ec2_snap_id(snapshots[0]))
2334
1881
        self.assertEquals(created_image.get('kernelId'), 'aki-00000001')
2335
1882
        self.assertEquals(created_image.get('ramdiskId'), 'ari-00000002')
2336
1883
        self.assertEquals(created_image.get('rootDeviceType'), 'ebs')
2338
1885
        self.assertNotEqual(virt_driver.get('powered_off'), no_reboot)
2339
1886
 
2340
1887
        self.cloud.terminate_instances(self.context, [ec2_instance_id])
2341
 
        for vol in volumes:
2342
 
            db.volume_destroy(self.context, vol)
2343
 
        for snap in snapshots:
2344
 
            db.snapshot_destroy(self.context, snap)
2345
 
        # TODO(yamahata): clean up snapshot created by CreateImage.
2346
1888
 
2347
1889
        self._restart_compute_service()
2348
1890
 
2366
1908
            create_volumes_and_snapshots=True)
2367
1909
 
2368
1910
        kwargs = {'image_id': 'ami-1',
2369
 
                  'instance_type': FLAGS.default_instance_type,
 
1911
                  'instance_type': CONF.default_instance_type,
2370
1912
                  'max_count': 1}
2371
1913
        ec2_instance_id = self._run_instance(**kwargs)
2372
1914
 
2382
1924
                                       delete_on_termination=False)
2383
1925
 
2384
1926
                def __getattr__(self, name):
2385
 
                    return self.values.get(name)
 
1927
                    """Properly delegate dotted lookups"""
 
1928
                    if name in self.__dict__['values']:
 
1929
                        return self.values.get(name)
 
1930
                    try:
 
1931
                        return self.__dict__[name]
 
1932
                    except KeyError:
 
1933
                        raise AttributeError
2386
1934
 
2387
1935
                def __getitem__(self, key):
2388
1936
                    return self.values.get(key)
2389
1937
 
 
1938
                def iteritems(self):
 
1939
                    return self.values.iteritems()
 
1940
 
2390
1941
            return [BDM()]
2391
1942
 
2392
1943
        self.stubs.Set(db, 'block_device_mapping_get_all_by_instance',
2465
2016
                }
2466
2017
        self.stubs.Set(self.cloud.compute_api, 'get', fake_get)
2467
2018
 
2468
 
        def fake_volume_get(ctxt, volume_id, session=None):
2469
 
            if volume_id == 87654321:
2470
 
                return {'id': volume_id,
2471
 
                        'attach_time': '13:56:24',
2472
 
                        'status': 'in-use'}
2473
 
            raise exception.VolumeNotFound(volume_id=volume_id)
2474
 
        self.stubs.Set(db, 'volume_get', fake_volume_get)
 
2019
        def fake_get_instance_uuid_by_ec2_id(ctxt, int_id):
 
2020
            if int_id == 305419896:
 
2021
                return 'e5fe5518-0288-4fa3-b0c4-c79764101b85'
 
2022
            raise exception.InstanceNotFound(instance_id=int_id)
 
2023
        self.stubs.Set(db, 'get_instance_uuid_by_ec2_id',
 
2024
                        fake_get_instance_uuid_by_ec2_id)
2475
2025
 
2476
2026
        get_attribute = functools.partial(
2477
2027
            self.cloud.describe_instance_attribute,
2525
2075
        def test_dia_iisb(expected_result, **kwargs):
2526
2076
            """test describe_instance_attribute
2527
2077
            attribute instance_initiated_shutdown_behavior"""
2528
 
            kwargs.update({'instance_type': FLAGS.default_instance_type,
 
2078
            kwargs.update({'instance_type': CONF.default_instance_type,
2529
2079
                           'max_count': 1})
2530
2080
            instance_id = self._run_instance(**kwargs)
2531
2081