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:
Martin Kopec 2019-03-25 12:48:01 +00:00
parent bc97c39df4
commit dbb2711c59
4 changed files with 48 additions and 15 deletions

View File

@ -19,7 +19,7 @@ from config_tempest.constants import LOG
class Flavors(object):
def __init__(self, client, allow_creation, conf):
def __init__(self, client, allow_creation, conf, no_rng=False):
"""Init.
:type client: FlavorsClient object from tempest lib
@ -29,6 +29,7 @@ class Flavors(object):
self.client = client
self.allow_creation = allow_creation
self._conf = conf
self.no_rng = no_rng
self.flavor_list = self.client.list_flavors()['flavors']
def create_tempest_flavors(self):
@ -53,10 +54,12 @@ class Flavors(object):
" exist", pref['key'], flavor_id)
else:
# 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)
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.
: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 vcpus: number of VCPUs for the flavor
: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)
if flavor_id is not None:
@ -74,6 +78,11 @@ class Flavors(object):
resp = self.client.create_flavor(name=flavor_name,
ram=ram, vcpus=vcpus,
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']
else:
if len(self.flavor_list) < 2:

View File

@ -261,6 +261,9 @@ def get_arg_parser():
help='Print debugging information.')
parser.add_argument('--verbose', '-v', action='store_true', default=False,
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,
help="""Simulate non-admin credentials.
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:
users = Users(clients.projects, clients.roles, clients.users, conf)
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()
image = services.get_service('image')
image.set_image_preferences(kwargs.get('image_disk_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)
has_neutron = services.is_service("network")
@ -568,6 +573,7 @@ def main():
image_path=args.image,
network_id=args.network_id,
non_admin=args.non_admin,
no_rng=args.no_rng,
os_cloud=args.os_cloud,
out=args.out,
overrides=args.overrides,

View File

@ -31,7 +31,7 @@ class ImageService(VersionedService):
disable_ssl_validation,
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.
:type disk_format: string
@ -39,6 +39,7 @@ class ImageService(VersionedService):
"""
self.disk_format = disk_format
self.non_admin = non_admin
self.no_rng = no_rng
def set_default_tempest_options(self, conf):
# When cirros is the image, set validation.image_ssh_user to cirros.
@ -189,10 +190,12 @@ class ImageService(VersionedService):
visibility = 'public'
with open(path, 'rb') as data:
image = self.client.create_image(name=name,
disk_format=self.disk_format,
container_format='bare',
visibility=visibility)
args = {'name': name, 'disk_format': self.disk_format,
'container_format': 'bare', 'visibility': visibility,
'hw_rng_model': 'virtio'}
if self.no_rng:
args.pop('hw_rng_model')
image = self.client.create_image(**args)
self.client.store_image_file(image['id'], data)
return image

View File

@ -54,8 +54,8 @@ class TestFlavors(BaseConfigTempestTest):
self.Service.create_tempest_flavors()
self.assertEqual(self.conf.get('compute', 'flavor_ref'), "FakeID")
self.assertEqual(self.conf.get('compute', 'flavor_ref_alt'), "FakeID")
calls = [mock.call('m1.nano', ram=64),
mock.call('m1.micro', ram=128)]
calls = [mock.call('m1.nano', ram=64, no_rng=False),
mock.call('m1.micro', ram=128, no_rng=False)]
mock_function.assert_has_calls(calls, any_order=True)
def check_call_of_discover_smallest_flavor(self):
@ -110,14 +110,29 @@ class TestFlavors(BaseConfigTempestTest):
# it should have ended in the except block above
self.assertTrue(False)
def test_create_flavor(self):
def _test_create_flavor(self, no_rng=False):
return_value = {"flavor": {"id": "MyFakeID", "name": "MyID"}}
self.Service.flavor_list = []
client = self.CLIENT_MOCK
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))
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'])
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):
return_value = {"flavors": self.FLAVORS_LIST}