Add RNG device to images and flavours
Upload new images and flavours with random number generator device [1]. It prevents the tests failing due to an image not ready for login error and can improve image boot time. [1] https://wiki.openstack.org/wiki/LibvirtVirtioRng Change-Id: I50114a3914e0df0e22706ca8a7a1649eb1ced31d
This commit is contained in:
parent
bc97c39df4
commit
dbb2711c59
@ -19,7 +19,7 @@ from config_tempest.constants import LOG
|
|||||||
|
|
||||||
|
|
||||||
class Flavors(object):
|
class Flavors(object):
|
||||||
def __init__(self, client, allow_creation, conf):
|
def __init__(self, client, allow_creation, conf, no_rng=False):
|
||||||
"""Init.
|
"""Init.
|
||||||
|
|
||||||
:type client: FlavorsClient object from tempest lib
|
:type client: FlavorsClient object from tempest lib
|
||||||
@ -29,6 +29,7 @@ class Flavors(object):
|
|||||||
self.client = client
|
self.client = client
|
||||||
self.allow_creation = allow_creation
|
self.allow_creation = allow_creation
|
||||||
self._conf = conf
|
self._conf = conf
|
||||||
|
self.no_rng = no_rng
|
||||||
self.flavor_list = self.client.list_flavors()['flavors']
|
self.flavor_list = self.client.list_flavors()['flavors']
|
||||||
|
|
||||||
def create_tempest_flavors(self):
|
def create_tempest_flavors(self):
|
||||||
@ -53,10 +54,12 @@ class Flavors(object):
|
|||||||
" exist", pref['key'], flavor_id)
|
" exist", pref['key'], flavor_id)
|
||||||
else:
|
else:
|
||||||
# create m1.nano/m1.micro flavor
|
# create m1.nano/m1.micro flavor
|
||||||
flavor_id = self.create_flavor(pref['name'], ram=pref['ram'])
|
flavor_id = self.create_flavor(pref['name'], ram=pref['ram'],
|
||||||
|
no_rng=self.no_rng)
|
||||||
self._conf.set('compute', pref['key'], flavor_id)
|
self._conf.set('compute', pref['key'], flavor_id)
|
||||||
|
|
||||||
def create_flavor(self, flavor_name, ram=64, vcpus=1, disk=1):
|
def create_flavor(self, flavor_name, ram=64, vcpus=1,
|
||||||
|
disk=1, no_rng=False):
|
||||||
"""Create flavors or try to discover two smallest ones available.
|
"""Create flavors or try to discover two smallest ones available.
|
||||||
|
|
||||||
:param flavor_name: flavor name to be created (usually m1.nano or
|
:param flavor_name: flavor name to be created (usually m1.nano or
|
||||||
@ -64,6 +67,7 @@ class Flavors(object):
|
|||||||
:param ram: memory of created flavor in MB
|
:param ram: memory of created flavor in MB
|
||||||
:param vcpus: number of VCPUs for the flavor
|
:param vcpus: number of VCPUs for the flavor
|
||||||
:param disk: size of disk for flavor in GB
|
:param disk: size of disk for flavor in GB
|
||||||
|
:param no_rng: boolean, if True, flavor will be created with RNG device
|
||||||
"""
|
"""
|
||||||
flavor_id = self.find_flavor_by_name(flavor_name)
|
flavor_id = self.find_flavor_by_name(flavor_name)
|
||||||
if flavor_id is not None:
|
if flavor_id is not None:
|
||||||
@ -74,6 +78,11 @@ class Flavors(object):
|
|||||||
resp = self.client.create_flavor(name=flavor_name,
|
resp = self.client.create_flavor(name=flavor_name,
|
||||||
ram=ram, vcpus=vcpus,
|
ram=ram, vcpus=vcpus,
|
||||||
disk=disk, id=None)
|
disk=disk, id=None)
|
||||||
|
args = {'flavor_id': resp['flavor']['id'],
|
||||||
|
'hw_rng:allowed': 'True'}
|
||||||
|
if no_rng:
|
||||||
|
args.pop('hw_rng:allowed')
|
||||||
|
self.client.set_flavor_extra_spec(**args)
|
||||||
return resp['flavor']['id']
|
return resp['flavor']['id']
|
||||||
else:
|
else:
|
||||||
if len(self.flavor_list) < 2:
|
if len(self.flavor_list) < 2:
|
||||||
|
@ -261,6 +261,9 @@ def get_arg_parser():
|
|||||||
help='Print debugging information.')
|
help='Print debugging information.')
|
||||||
parser.add_argument('--verbose', '-v', action='store_true', default=False,
|
parser.add_argument('--verbose', '-v', action='store_true', default=False,
|
||||||
help='Print more information about the execution.')
|
help='Print more information about the execution.')
|
||||||
|
parser.add_argument('--no-rng', action='store_true', default=False,
|
||||||
|
help="""Create new flavors and upload images without
|
||||||
|
random number generator device.""")
|
||||||
parser.add_argument('--non-admin', action='store_true', default=False,
|
parser.add_argument('--non-admin', action='store_true', default=False,
|
||||||
help="""Simulate non-admin credentials.
|
help="""Simulate non-admin credentials.
|
||||||
When True, the credentials are used as
|
When True, the credentials are used as
|
||||||
@ -509,13 +512,15 @@ def config_tempest(**kwargs):
|
|||||||
if kwargs.get('create', False) and kwargs.get('test_accounts') is None:
|
if kwargs.get('create', False) and kwargs.get('test_accounts') is None:
|
||||||
users = Users(clients.projects, clients.roles, clients.users, conf)
|
users = Users(clients.projects, clients.roles, clients.users, conf)
|
||||||
users.create_tempest_users(services.is_service('orchestration'))
|
users.create_tempest_users(services.is_service('orchestration'))
|
||||||
flavors = Flavors(clients.flavors, kwargs.get('create', False), conf)
|
flavors = Flavors(clients.flavors, kwargs.get('create', False), conf,
|
||||||
|
no_rng=kwargs.get('no_rng', False))
|
||||||
flavors.create_tempest_flavors()
|
flavors.create_tempest_flavors()
|
||||||
|
|
||||||
image = services.get_service('image')
|
image = services.get_service('image')
|
||||||
image.set_image_preferences(kwargs.get('image_disk_format',
|
image.set_image_preferences(kwargs.get('image_disk_format',
|
||||||
C.DEFAULT_IMAGE_FORMAT),
|
C.DEFAULT_IMAGE_FORMAT),
|
||||||
kwargs.get('non_admin', False))
|
kwargs.get('non_admin', False),
|
||||||
|
no_rng=kwargs.get('no_rng', False))
|
||||||
image.create_tempest_images(conf)
|
image.create_tempest_images(conf)
|
||||||
|
|
||||||
has_neutron = services.is_service("network")
|
has_neutron = services.is_service("network")
|
||||||
@ -568,6 +573,7 @@ def main():
|
|||||||
image_path=args.image,
|
image_path=args.image,
|
||||||
network_id=args.network_id,
|
network_id=args.network_id,
|
||||||
non_admin=args.non_admin,
|
non_admin=args.non_admin,
|
||||||
|
no_rng=args.no_rng,
|
||||||
os_cloud=args.os_cloud,
|
os_cloud=args.os_cloud,
|
||||||
out=args.out,
|
out=args.out,
|
||||||
overrides=args.overrides,
|
overrides=args.overrides,
|
||||||
|
@ -31,7 +31,7 @@ class ImageService(VersionedService):
|
|||||||
disable_ssl_validation,
|
disable_ssl_validation,
|
||||||
client)
|
client)
|
||||||
|
|
||||||
def set_image_preferences(self, disk_format, non_admin):
|
def set_image_preferences(self, disk_format, non_admin, no_rng=False):
|
||||||
"""Sets image prefferences.
|
"""Sets image prefferences.
|
||||||
|
|
||||||
:type disk_format: string
|
:type disk_format: string
|
||||||
@ -39,6 +39,7 @@ class ImageService(VersionedService):
|
|||||||
"""
|
"""
|
||||||
self.disk_format = disk_format
|
self.disk_format = disk_format
|
||||||
self.non_admin = non_admin
|
self.non_admin = non_admin
|
||||||
|
self.no_rng = no_rng
|
||||||
|
|
||||||
def set_default_tempest_options(self, conf):
|
def set_default_tempest_options(self, conf):
|
||||||
# When cirros is the image, set validation.image_ssh_user to cirros.
|
# When cirros is the image, set validation.image_ssh_user to cirros.
|
||||||
@ -189,10 +190,12 @@ class ImageService(VersionedService):
|
|||||||
visibility = 'public'
|
visibility = 'public'
|
||||||
|
|
||||||
with open(path, 'rb') as data:
|
with open(path, 'rb') as data:
|
||||||
image = self.client.create_image(name=name,
|
args = {'name': name, 'disk_format': self.disk_format,
|
||||||
disk_format=self.disk_format,
|
'container_format': 'bare', 'visibility': visibility,
|
||||||
container_format='bare',
|
'hw_rng_model': 'virtio'}
|
||||||
visibility=visibility)
|
if self.no_rng:
|
||||||
|
args.pop('hw_rng_model')
|
||||||
|
image = self.client.create_image(**args)
|
||||||
self.client.store_image_file(image['id'], data)
|
self.client.store_image_file(image['id'], data)
|
||||||
return image
|
return image
|
||||||
|
|
||||||
|
@ -54,8 +54,8 @@ class TestFlavors(BaseConfigTempestTest):
|
|||||||
self.Service.create_tempest_flavors()
|
self.Service.create_tempest_flavors()
|
||||||
self.assertEqual(self.conf.get('compute', 'flavor_ref'), "FakeID")
|
self.assertEqual(self.conf.get('compute', 'flavor_ref'), "FakeID")
|
||||||
self.assertEqual(self.conf.get('compute', 'flavor_ref_alt'), "FakeID")
|
self.assertEqual(self.conf.get('compute', 'flavor_ref_alt'), "FakeID")
|
||||||
calls = [mock.call('m1.nano', ram=64),
|
calls = [mock.call('m1.nano', ram=64, no_rng=False),
|
||||||
mock.call('m1.micro', ram=128)]
|
mock.call('m1.micro', ram=128, no_rng=False)]
|
||||||
mock_function.assert_has_calls(calls, any_order=True)
|
mock_function.assert_has_calls(calls, any_order=True)
|
||||||
|
|
||||||
def check_call_of_discover_smallest_flavor(self):
|
def check_call_of_discover_smallest_flavor(self):
|
||||||
@ -110,14 +110,29 @@ class TestFlavors(BaseConfigTempestTest):
|
|||||||
# it should have ended in the except block above
|
# it should have ended in the except block above
|
||||||
self.assertTrue(False)
|
self.assertTrue(False)
|
||||||
|
|
||||||
def test_create_flavor(self):
|
def _test_create_flavor(self, no_rng=False):
|
||||||
return_value = {"flavor": {"id": "MyFakeID", "name": "MyID"}}
|
return_value = {"flavor": {"id": "MyFakeID", "name": "MyID"}}
|
||||||
self.Service.flavor_list = []
|
self.Service.flavor_list = []
|
||||||
|
client = self.CLIENT_MOCK
|
||||||
mock_function = mock.Mock(return_value=return_value)
|
mock_function = mock.Mock(return_value=return_value)
|
||||||
self.useFixture(MonkeyPatch(self.CLIENT_MOCK + '.create_flavor',
|
self.useFixture(MonkeyPatch(client + '.create_flavor', mock_function))
|
||||||
|
mock_function = mock.Mock(return_value={})
|
||||||
|
self.useFixture(MonkeyPatch(client + '.set_flavor_extra_spec',
|
||||||
mock_function))
|
mock_function))
|
||||||
resp = self.Service.create_flavor(flavor_name="MyID")
|
resp = self.Service.create_flavor(flavor_name="MyID", no_rng=no_rng)
|
||||||
self.assertEqual(resp, return_value['flavor']['id'])
|
self.assertEqual(resp, return_value['flavor']['id'])
|
||||||
|
return mock_function
|
||||||
|
|
||||||
|
def test_create_flavor_rng(self):
|
||||||
|
mock_function = self._test_create_flavor()
|
||||||
|
calls = [mock.call(flavor_id='MyFakeID', **{'hw_rng:allowed': 'True'})]
|
||||||
|
mock_function.assert_has_calls(calls, any_order=True)
|
||||||
|
|
||||||
|
def test_create_flavor_no_rng(self):
|
||||||
|
self.Service.no_rng = True
|
||||||
|
mock_function = self._test_create_flavor(no_rng=True)
|
||||||
|
calls = [mock.call(flavor_id='MyFakeID')]
|
||||||
|
mock_function.assert_has_calls(calls, any_order=True)
|
||||||
|
|
||||||
def test_find_flavor_by_id(self):
|
def test_find_flavor_by_id(self):
|
||||||
return_value = {"flavors": self.FLAVORS_LIST}
|
return_value = {"flavors": self.FLAVORS_LIST}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user