Skip to content

Commit

Permalink
test_utils: Ensure diverse placement of test instances
Browse files Browse the repository at this point in the history
Use the Nova Server Groups API to influence placement of test
instances.

Fixes #641
  • Loading branch information
fnordahl committed Feb 9, 2022
1 parent e109ded commit d62215d
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 6 deletions.
22 changes: 18 additions & 4 deletions zaza/openstack/charm_tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -616,14 +616,20 @@ def setUpClass(cls, application_name=None, model_alias=None):
def resource_cleanup(self):
"""Remove test resources."""
try:
logging.info('Removing instances launched by test ({}*)'
logging.info('Removing resources created by test ({}*)'
.format(self.RESOURCE_PREFIX))
for server in self.nova_client.servers.list():
if server.name.startswith(self.RESOURCE_PREFIX):
openstack_utils.delete_resource(
self.nova_client.servers,
server.id,
msg="server")
for server_group in self.nova_client.server_groups.list():
if server_group.name.startswith(self.RESOURCE_PREFIX):
openstack_utils.delete_resource(
self.nova_client.server_groups,
server_group.id,
msg="server group")
except AssertionError as e:
# Resource failed to be removed within the expected time frame,
# log this fact and carry on.
Expand All @@ -634,7 +640,7 @@ def resource_cleanup(self):
pass

def launch_guest(self, guest_name, userdata=None, use_boot_volume=False,
instance_key=None):
instance_key=None, scheduler_hints=None):
"""Launch one guest to use in tests.
Note that it is up to the caller to have set the RESOURCE_PREFIX class
Expand All @@ -651,6 +657,9 @@ def launch_guest(self, guest_name, userdata=None, use_boot_volume=False,
:type use_boot_volume: boolean
:param instance_key: Key to collect associated config data with.
:type instance_key: Optional[str]
:param scheduler_hints: arbitrary key-value pairs specified by the
client to help boot an instance.
:type scheduler_hints: Optional[Dict[str,str]]
:returns: Nova instance objects
:rtype: Server
"""
Expand Down Expand Up @@ -678,7 +687,8 @@ def launch_guest(self, guest_name, userdata=None, use_boot_volume=False,
instance_key,
vm_name=instance_name,
use_boot_volume=use_boot_volume,
userdata=userdata)
userdata=userdata,
scheduler_hints=scheduler_hints)

def launch_guests(self, userdata=None):
"""Launch two guests to use in tests.
Expand All @@ -691,12 +701,16 @@ def launch_guests(self, userdata=None):
:returns: List of launched Nova instance objects
:rtype: List[Server]
"""
server_group = configure_guest.create_server_group(
self.RESOURCE_PREFIX, policy='anti-affinity')

launched_instances = []
for guest_number in range(1, 2+1):
launched_instances.append(
self.launch_guest(
guest_name='ins-{}'.format(guest_number),
userdata=userdata))
userdata=userdata,
scheduler_hints={'group': server_group.id}))
return launched_instances

def retrieve_guest(self, guest_name):
Expand Down
30 changes: 28 additions & 2 deletions zaza/openstack/configure/guest.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,32 @@
'bootstring': 'finished at'}}


def create_server_group(name, policy=None):
"""Create a server group for influencing instance placement.
:param name: Name of server group.
:type name: str
:param policy: Policy for group, one of ('affinity', 'anti-affinity',
'soft-affinity', 'soft-anti-affinity'). Default: 'affinity'
:type policy: Optional[str]
:param rules
:returns: ServerGroup resource.
:rtype: novaclient.v2.server_groups.ServerGroup
:raises: ValueError
"""
if policy and policy not in ('affinity', 'anti-affinity', 'soft-affinity',
'soft-anti-affinity'):
raise ValueError

keystone_session = openstack_utils.get_overcloud_keystone_session()
nova_client = openstack_utils.get_nova_session_client(keystone_session)
return nova_client.server_groups.create(name, policy)


def launch_instance(instance_key, use_boot_volume=False, vm_name=None,
private_network_name=None, image_name=None,
flavor_name=None, external_network_name=None, meta=None,
userdata=None):
userdata=None, scheduler_hints=None):
"""Launch an instance.
:param instance_key: Key to collect associated config data with.
Expand All @@ -71,6 +93,9 @@ def launch_instance(instance_key, use_boot_volume=False, vm_name=None,
:type meta: dict
:param userdata: Configuration to use upon launch, used by cloud-init.
:type userdata: str
:param scheduler_hints: arbitrary key-value pairs specified by the client
to help boot an instance.
:type scheduler_hints: Optional[Dict[str,str]]
:returns: the created instance
:rtype: novaclient.Server
"""
Expand Down Expand Up @@ -117,7 +142,8 @@ def launch_instance(instance_key, use_boot_volume=False, vm_name=None,
key_name=nova_utils.KEYPAIR_NAME,
meta=meta,
nics=nics,
userdata=userdata)
userdata=userdata,
scheduler_hints=scheduler_hints)

# Test Instance is ready.
logging.info('Checking instance is active')
Expand Down

0 comments on commit d62215d

Please sign in to comment.