Skip to content

Commit e6b0473

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "compute: Add functional tests for --block-device"
2 parents 274d1ee + 7c1d6f7 commit e6b0473

3 files changed

Lines changed: 169 additions & 53 deletions

File tree

openstackclient/compute/v2/server.py

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -832,13 +832,12 @@ def get_parser(self, prog_name):
832832
action=parseractions.MultiKeyValueAction,
833833
dest='block_devices',
834834
default=[],
835-
required_keys=[
836-
'boot_index',
837-
],
835+
required_keys=[],
838836
optional_keys=[
839837
'uuid', 'source_type', 'destination_type',
840-
'disk_bus', 'device_type', 'device_name', 'guest_format',
841-
'volume_size', 'volume_type', 'delete_on_termination', 'tag',
838+
'disk_bus', 'device_type', 'device_name', 'volume_size',
839+
'guest_format', 'boot_index', 'delete_on_termination', 'tag',
840+
'volume_type',
842841
],
843842
help=_(
844843
'Create a block device on the server.\n'
@@ -1336,14 +1335,15 @@ def _match_image(image_api, wanted_properties):
13361335
block_device_mapping_v2.append(mapping)
13371336

13381337
for mapping in parsed_args.block_devices:
1339-
try:
1340-
mapping['boot_index'] = int(mapping['boot_index'])
1341-
except ValueError:
1342-
msg = _(
1343-
'The boot_index key of --block-device should be an '
1344-
'integer'
1345-
)
1346-
raise exceptions.CommandError(msg)
1338+
if 'boot_index' in mapping:
1339+
try:
1340+
mapping['boot_index'] = int(mapping['boot_index'])
1341+
except ValueError:
1342+
msg = _(
1343+
'The boot_index key of --block-device should be an '
1344+
'integer'
1345+
)
1346+
raise exceptions.CommandError(msg)
13471347

13481348
if 'tag' in mapping and (
13491349
compute_client.api_version < api_versions.APIVersion('2.42')
@@ -1383,9 +1383,9 @@ def _match_image(image_api, wanted_properties):
13831383
)
13841384
raise exceptions.CommandError(msg)
13851385
else:
1386-
if mapping['source_type'] in ('image', 'blank'):
1386+
if mapping['source_type'] in ('blank',):
13871387
mapping['destination_type'] = 'local'
1388-
else: # volume, snapshot
1388+
else: # volume, image, snapshot
13891389
mapping['destination_type'] = 'volume'
13901390

13911391
if 'delete_on_termination' in mapping:

openstackclient/tests/functional/compute/v2/test_server.py

Lines changed: 148 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -574,7 +574,90 @@ def test_server_boot_from_volume(self):
574574
cmd_output['status'],
575575
)
576576

577-
def test_server_boot_with_bdm_snapshot(self):
577+
def _test_server_boot_with_bdm_volume(self, use_legacy):
578+
"""Test server create from volume, server delete"""
579+
# get volume status wait function
580+
volume_wait_for = volume_common.BaseVolumeTests.wait_for_status
581+
582+
# create source empty volume
583+
volume_name = uuid.uuid4().hex
584+
cmd_output = json.loads(self.openstack(
585+
'volume create -f json ' +
586+
'--size 1 ' +
587+
volume_name
588+
))
589+
volume_id = cmd_output["id"]
590+
self.assertIsNotNone(volume_id)
591+
self.addCleanup(self.openstack, 'volume delete ' + volume_name)
592+
self.assertEqual(volume_name, cmd_output['name'])
593+
volume_wait_for("volume", volume_name, "available")
594+
595+
if use_legacy:
596+
bdm_arg = f'--block-device-mapping vdb={volume_name}'
597+
else:
598+
bdm_arg = (
599+
f'--block-device '
600+
f'device_name=vdb,source_type=volume,boot_index=1,'
601+
f'uuid={volume_id}'
602+
)
603+
604+
# create server
605+
server_name = uuid.uuid4().hex
606+
server = json.loads(self.openstack(
607+
'server create -f json ' +
608+
'--flavor ' + self.flavor_name + ' ' +
609+
'--image ' + self.image_name + ' ' +
610+
bdm_arg + ' ' +
611+
self.network_arg + ' ' +
612+
'--wait ' +
613+
server_name
614+
))
615+
self.assertIsNotNone(server["id"])
616+
self.addCleanup(self.openstack, 'server delete --wait ' + server_name)
617+
self.assertEqual(
618+
server_name,
619+
server['name'],
620+
)
621+
622+
# check server volumes_attached, format is
623+
# {"volumes_attached": "id='2518bc76-bf0b-476e-ad6b-571973745bb5'",}
624+
cmd_output = json.loads(self.openstack(
625+
'server show -f json ' +
626+
server_name
627+
))
628+
volumes_attached = cmd_output['volumes_attached']
629+
self.assertIsNotNone(volumes_attached)
630+
631+
# check volumes
632+
cmd_output = json.loads(self.openstack(
633+
'volume show -f json ' +
634+
volume_name
635+
))
636+
attachments = cmd_output['attachments']
637+
self.assertEqual(
638+
1,
639+
len(attachments),
640+
)
641+
self.assertEqual(
642+
server['id'],
643+
attachments[0]['server_id'],
644+
)
645+
self.assertEqual(
646+
"in-use",
647+
cmd_output['status'],
648+
)
649+
650+
def test_server_boot_with_bdm_volume(self):
651+
"""Test server create from image with bdm volume, server delete"""
652+
self._test_server_boot_with_bdm_volume(use_legacy=False)
653+
654+
# TODO(stephenfin): Remove when we drop support for the
655+
# '--block-device-mapping' option
656+
def test_server_boot_with_bdm_volume_legacy(self):
657+
"""Test server create from image with bdm volume, server delete"""
658+
self._test_server_boot_with_bdm_volume(use_legacy=True)
659+
660+
def _test_server_boot_with_bdm_snapshot(self, use_legacy):
578661
"""Test server create from image with bdm snapshot, server delete"""
579662
# get volume status wait function
580663
volume_wait_for = volume_common.BaseVolumeTests.wait_for_status
@@ -588,12 +671,8 @@ def test_server_boot_with_bdm_snapshot(self):
588671
empty_volume_name
589672
))
590673
self.assertIsNotNone(cmd_output["id"])
591-
self.addCleanup(self.openstack,
592-
'volume delete ' + empty_volume_name)
593-
self.assertEqual(
594-
empty_volume_name,
595-
cmd_output['name'],
596-
)
674+
self.addCleanup(self.openstack, 'volume delete ' + empty_volume_name)
675+
self.assertEqual(empty_volume_name, cmd_output['name'])
597676
volume_wait_for("volume", empty_volume_name, "available")
598677

599678
# create snapshot of source empty volume
@@ -603,7 +682,8 @@ def test_server_boot_with_bdm_snapshot(self):
603682
'--volume ' + empty_volume_name + ' ' +
604683
empty_snapshot_name
605684
))
606-
self.assertIsNotNone(cmd_output["id"])
685+
empty_snapshot_id = cmd_output["id"]
686+
self.assertIsNotNone(empty_snapshot_id)
607687
# Deleting volume snapshot take time, so we need to wait until the
608688
# snapshot goes. Entries registered by self.addCleanup will be called
609689
# in the reverse order, so we need to register wait_for_delete first.
@@ -617,14 +697,26 @@ def test_server_boot_with_bdm_snapshot(self):
617697
)
618698
volume_wait_for("volume snapshot", empty_snapshot_name, "available")
619699

700+
if use_legacy:
701+
bdm_arg = (
702+
f'--block-device-mapping '
703+
f'vdb={empty_snapshot_name}:snapshot:1:true'
704+
)
705+
else:
706+
bdm_arg = (
707+
f'--block-device '
708+
f'device_name=vdb,uuid={empty_snapshot_id},'
709+
f'source_type=snapshot,volume_size=1,'
710+
f'delete_on_termination=true,boot_index=1'
711+
)
712+
620713
# create server with bdm snapshot
621714
server_name = uuid.uuid4().hex
622715
server = json.loads(self.openstack(
623716
'server create -f json ' +
624717
'--flavor ' + self.flavor_name + ' ' +
625718
'--image ' + self.image_name + ' ' +
626-
'--block-device-mapping '
627-
'vdb=' + empty_snapshot_name + ':snapshot:1:true ' +
719+
bdm_arg + ' ' +
628720
self.network_arg + ' ' +
629721
'--wait ' +
630722
server_name
@@ -681,14 +773,50 @@ def test_server_boot_with_bdm_snapshot(self):
681773
# the attached volume had been deleted
682774
pass
683775

684-
def test_server_boot_with_bdm_image(self):
776+
def test_server_boot_with_bdm_snapshot(self):
777+
"""Test server create from image with bdm snapshot, server delete"""
778+
self._test_server_boot_with_bdm_snapshot(use_legacy=False)
779+
780+
# TODO(stephenfin): Remove when we drop support for the
781+
# '--block-device-mapping' option
782+
def test_server_boot_with_bdm_snapshot_legacy(self):
783+
"""Test server create from image with bdm snapshot, server delete"""
784+
self._test_server_boot_with_bdm_snapshot(use_legacy=True)
785+
786+
def _test_server_boot_with_bdm_image(self, use_legacy):
685787
# Tests creating a server where the root disk is backed by the given
686788
# --image but a --block-device-mapping with type=image is provided so
687789
# that the compute service creates a volume from that image and
688790
# attaches it as a non-root volume on the server. The block device is
689791
# marked as delete_on_termination=True so it will be automatically
690792
# deleted when the server is deleted.
691793

794+
if use_legacy:
795+
# This means create a 1GB volume from the specified image, attach
796+
# it to the server at /dev/vdb and delete the volume when the
797+
# server is deleted.
798+
bdm_arg = (
799+
f'--block-device-mapping '
800+
f'vdb={self.image_name}:image:1:true '
801+
)
802+
else:
803+
# get image ID
804+
cmd_output = json.loads(self.openstack(
805+
'image show -f json ' +
806+
self.image_name
807+
))
808+
image_id = cmd_output['id']
809+
810+
# This means create a 1GB volume from the specified image, attach
811+
# it to the server at /dev/vdb and delete the volume when the
812+
# server is deleted.
813+
bdm_arg = (
814+
f'--block-device '
815+
f'device_name=vdb,uuid={image_id},'
816+
f'source_type=image,volume_size=1,'
817+
f'delete_on_termination=true,boot_index=1'
818+
)
819+
692820
# create server with bdm type=image
693821
# NOTE(mriedem): This test is a bit unrealistic in that specifying the
694822
# same image in the block device as the --image option does not really
@@ -700,11 +828,7 @@ def test_server_boot_with_bdm_image(self):
700828
'server create -f json ' +
701829
'--flavor ' + self.flavor_name + ' ' +
702830
'--image ' + self.image_name + ' ' +
703-
'--block-device-mapping '
704-
# This means create a 1GB volume from the specified image, attach
705-
# it to the server at /dev/vdb and delete the volume when the
706-
# server is deleted.
707-
'vdb=' + self.image_name + ':image:1:true ' +
831+
bdm_arg + ' ' +
708832
self.network_arg + ' ' +
709833
'--wait ' +
710834
server_name
@@ -768,6 +892,14 @@ def test_server_boot_with_bdm_image(self):
768892
# the attached volume had been deleted
769893
pass
770894

895+
def test_server_boot_with_bdm_image(self):
896+
self._test_server_boot_with_bdm_image(use_legacy=False)
897+
898+
# TODO(stephenfin): Remove when we drop support for the
899+
# '--block-device-mapping' option
900+
def test_server_boot_with_bdm_image_legacy(self):
901+
self._test_server_boot_with_bdm_image(use_legacy=True)
902+
771903
def test_boot_from_volume(self):
772904
# Tests creating a server using --image and --boot-from-volume where
773905
# the compute service will create a root volume of the specified size

openstackclient/tests/unit/compute/v2/test_server.py

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2029,7 +2029,7 @@ def test_server_create_with_snapshot(self):
20292029
self.assertEqual(self.datalist(), data)
20302030

20312031
def test_server_create_with_block_device(self):
2032-
block_device = f'uuid={self.volume.id},source_type=volume,boot_index=1'
2032+
block_device = f'uuid={self.volume.id},source_type=volume'
20332033
arglist = [
20342034
'--image', 'image1',
20352035
'--flavor', self.flavor.id,
@@ -2043,7 +2043,6 @@ def test_server_create_with_block_device(self):
20432043
{
20442044
'uuid': self.volume.id,
20452045
'source_type': 'volume',
2046-
'boot_index': '1',
20472046
},
20482047
]),
20492048
('server_name', self.new_server.name),
@@ -2069,7 +2068,6 @@ def test_server_create_with_block_device(self):
20692068
'uuid': self.volume.id,
20702069
'source_type': 'volume',
20712070
'destination_type': 'volume',
2072-
'boot_index': 1,
20732071
}],
20742072
'nics': [],
20752073
'scheduler_hints': {},
@@ -2171,20 +2169,6 @@ def test_server_create_with_block_device_full(self):
21712169
self.assertEqual(self.columns, columns)
21722170
self.assertEqual(self.datalist(), data)
21732171

2174-
def test_server_create_with_block_device_no_boot_index(self):
2175-
block_device = \
2176-
f'uuid={self.volume.name},source_type=volume'
2177-
arglist = [
2178-
'--image', 'image1',
2179-
'--flavor', self.flavor.id,
2180-
'--block-device', block_device,
2181-
self.new_server.name,
2182-
]
2183-
self.assertRaises(
2184-
argparse.ArgumentTypeError,
2185-
self.check_parser,
2186-
self.cmd, arglist, [])
2187-
21882172
def test_server_create_with_block_device_invalid_boot_index(self):
21892173
block_device = \
21902174
f'uuid={self.volume.name},source_type=volume,boot_index=foo'
@@ -2201,7 +2185,7 @@ def test_server_create_with_block_device_invalid_boot_index(self):
22012185
self.assertIn('The boot_index key of --block-device ', str(ex))
22022186

22032187
def test_server_create_with_block_device_invalid_source_type(self):
2204-
block_device = f'uuid={self.volume.name},source_type=foo,boot_index=1'
2188+
block_device = f'uuid={self.volume.name},source_type=foo'
22052189
arglist = [
22062190
'--image', 'image1',
22072191
'--flavor', self.flavor.id,
@@ -2216,7 +2200,7 @@ def test_server_create_with_block_device_invalid_source_type(self):
22162200

22172201
def test_server_create_with_block_device_invalid_destination_type(self):
22182202
block_device = \
2219-
f'uuid={self.volume.name},destination_type=foo,boot_index=1'
2203+
f'uuid={self.volume.name},destination_type=foo'
22202204
arglist = [
22212205
'--image', 'image1',
22222206
'--flavor', self.flavor.id,
@@ -2231,7 +2215,7 @@ def test_server_create_with_block_device_invalid_destination_type(self):
22312215

22322216
def test_server_create_with_block_device_invalid_shutdown(self):
22332217
block_device = \
2234-
f'uuid={self.volume.name},delete_on_termination=foo,boot_index=1'
2218+
f'uuid={self.volume.name},delete_on_termination=foo'
22352219
arglist = [
22362220
'--image', 'image1',
22372221
'--flavor', self.flavor.id,
@@ -2250,7 +2234,7 @@ def test_server_create_with_block_device_tag_pre_v242(self):
22502234
'2.41')
22512235

22522236
block_device = \
2253-
f'uuid={self.volume.name},tag=foo,boot_index=1'
2237+
f'uuid={self.volume.name},tag=foo'
22542238
arglist = [
22552239
'--image', 'image1',
22562240
'--flavor', self.flavor.id,
@@ -2269,7 +2253,7 @@ def test_server_create_with_block_device_volume_type_pre_v267(self):
22692253
self.app.client_manager.compute.api_version = api_versions.APIVersion(
22702254
'2.66')
22712255

2272-
block_device = f'uuid={self.volume.name},volume_type=foo,boot_index=1'
2256+
block_device = f'uuid={self.volume.name},volume_type=foo'
22732257
arglist = [
22742258
'--image', 'image1',
22752259
'--flavor', self.flavor.id,

0 commit comments

Comments
 (0)