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 Jul 19, 2022
1 parent b248962 commit 5f2981e
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 6 deletions.
23 changes: 19 additions & 4 deletions zaza/openstack/charm_tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -733,14 +733,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 @@ -752,7 +758,8 @@ def resource_cleanup(self):

def launch_guest(self, guest_name, userdata=None, use_boot_volume=False,
instance_key=None, flavor_name=None,
attach_to_external_network=False):
attach_to_external_network=False,
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 @@ -772,6 +779,9 @@ def launch_guest(self, guest_name, userdata=None, use_boot_volume=False,
:param attach_to_external_network: Attach instance directly to external
network.
:type attach_to_external_network: bool
: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 @@ -801,7 +811,8 @@ def launch_guest(self, guest_name, userdata=None, use_boot_volume=False,
use_boot_volume=use_boot_volume,
userdata=userdata,
flavor_name=flavor_name,
attach_to_external_network=attach_to_external_network)
attach_to_external_network=attach_to_external_network,
scheduler_hints=scheduler_hints)

def launch_guests(self, userdata=None, attach_to_external_network=False,
flavor_name=None):
Expand All @@ -818,14 +829,18 @@ def launch_guests(self, userdata=None, attach_to_external_network=False,
: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,
attach_to_external_network=attach_to_external_network,
flavor_name=flavor_name))
flavor_name=flavor_name,
scheduler_hints={'group': server_group.id}))
return launched_instances

def retrieve_guest(self, guest_name):
Expand Down
31 changes: 29 additions & 2 deletions zaza/openstack/configure/guest.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,33 @@
'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, attach_to_external_network=False):
userdata=None, attach_to_external_network=False,
scheduler_hints=None):
"""Launch an instance.
:param instance_key: Key to collect associated config data with.
Expand All @@ -79,6 +102,9 @@ def launch_instance(instance_key, use_boot_volume=False, vm_name=None,
:param attach_to_external_network: Attach instance directly to external
network.
:type attach_to_external_network: bool
: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 @@ -131,7 +157,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 5f2981e

Please sign in to comment.