tests: Add helpers for suspend, resume and reboot of server

We will use this in a later test, but some tests that could have
benefited from these are reworked now to validate the approach.

Change-Id: I03bcd6753ed776d2ee216dcdca48514e5da8c43e
Signed-off-by: Stephen Finucane <stephenfin@redhat.com>
This commit is contained in:
Stephen Finucane 2020-07-15 14:52:11 +01:00
parent 1c2cccab71
commit 0f61324893
5 changed files with 54 additions and 67 deletions

View File

@ -393,6 +393,20 @@ class InstanceHelperMixin:
self.api.delete_server(server['id'])
self._wait_until_deleted(server)
def _reboot_server(self, server, hard=False, expected_state='ACTIVE'):
"""Reboot a server."""
self.api.post_server_action(
server['id'], {'reboot': {'type': 'HARD' if hard else 'SOFT'}},
)
fake_notifier.wait_for_versioned_notifications('instance.reboot.end')
return self._wait_for_state_change(server, expected_state)
def _resize_server(self, server, flavor_id):
self.api.post_server_action(
server['id'], {'resize': {'flavorRef': flavor_id}})
fake_notifier.wait_for_versioned_notifications('instance.resize.end')
return self._wait_for_state_change(server, 'VERIFY_RESIZE')
def _confirm_resize(self, server):
self.api.post_server_action(server['id'], {'confirmResize': None})
server = self._wait_for_state_change(server, 'ACTIVE')
@ -415,30 +429,26 @@ class InstanceHelperMixin:
'instance.resize_revert.end')
return server
def _migrate_or_resize(self, server, request):
if 'resize' not in request and 'migrate' not in request:
raise Exception('_migrate_or_resize only supports resize or '
'migrate requests.')
self.api.post_server_action(server['id'], request)
self._wait_for_state_change(server, 'VERIFY_RESIZE')
def _resize_server(self, server, new_flavor):
resize_req = {
'resize': {
'flavorRef': new_flavor
}
}
self._migrate_or_resize(server, resize_req)
def _live_migrate(self, server, migration_expected_state,
server_expected_state='ACTIVE'):
self.api.post_server_action(
server['id'],
{'os-migrateLive': {'host': None,
'block_migration': 'auto'}})
{'os-migrateLive': {'host': None, 'block_migration': 'auto'}})
self._wait_for_state_change(server, server_expected_state)
self._wait_for_migration_status(server, [migration_expected_state])
def _suspend_server(self, server, expected_state='SUSPENDED'):
"""Suspend a server."""
self.api.post_server_action(server['id'], {'suspend': {}})
fake_notifier.wait_for_versioned_notifications('instance.suspend.end')
return self._wait_for_state_change(server, expected_state)
def _resume_server(self, server, expected_state='ACTIVE'):
"""Resume a server."""
self.api.post_server_action(server['id'], {'resume': {}})
fake_notifier.wait_for_versioned_notifications('instance.resume.end')
return self._wait_for_state_change(server, expected_state)
class PlacementHelperMixin:
"""A helper mixin for interacting with placement."""
@ -827,7 +837,13 @@ class PlacementInstanceHelperMixin(InstanceHelperMixin, PlacementHelperMixin):
self, server, request, old_flavor, new_flavor, source_rp_uuid,
dest_rp_uuid,
):
self._migrate_or_resize(server, request)
if 'resize' not in request and 'migrate' not in request:
raise Exception(
'_move_and_check_allocations only supports resize or migrate '
'requests.')
self.api.post_server_action(server['id'], request)
self._wait_for_state_change(server, 'VERIFY_RESIZE')
def _check_allocation():
self.assertFlavorMatchesUsage(source_rp_uuid, old_flavor)

View File

@ -59,13 +59,6 @@ class RegressionTest1835822(
server = self.api.post_server({'server': basic_server})
return self._wait_for_state_change(server, 'ACTIVE')
def _hard_reboot_server(self, active_server):
args = {"reboot": {"type": "HARD"}}
self.api.api_post('servers/%s/action' %
active_server['id'], args)
fake_notifier.wait_for_versioned_notifications('instance.reboot.end')
return self._wait_for_state_change(active_server, 'ACTIVE')
def _rebuild_server(self, active_server):
args = {"rebuild": {"imageRef": self.image_ref_1}}
self.api.api_post('servers/%s/action' %
@ -112,7 +105,7 @@ class RegressionTest1835822(
self.flags(force_config_drive=True)
active_server = self._create_active_server()
self.assertTrue(active_server['config_drive'])
active_server = self._hard_reboot_server(active_server)
active_server = self._reboot_server(active_server, hard=True)
self.assertTrue(active_server['config_drive'])
def test_create_server_config_drive_reboot_after_conf_change(self):
@ -132,13 +125,14 @@ class RegressionTest1835822(
# this server was created with force_config_drive=true
# so assert now that force_config_drive is false it does
# not override the value it was booted with.
with_config_drive = self._hard_reboot_server(with_config_drive)
with_config_drive = self._reboot_server(with_config_drive, hard=True)
self.assertTrue(with_config_drive['config_drive'])
# this server was booted with force_config_drive=False so
# assert that it's config drive setting is not overridden
self.flags(force_config_drive=True)
without_config_drive = self._hard_reboot_server(without_config_drive)
without_config_drive = self._reboot_server(
without_config_drive, hard=True)
self.assertEqual('', without_config_drive['config_drive'])
def test_create_server_config_drive_rebuild_after_conf_change(self):

View File

@ -1116,13 +1116,11 @@ class TestMultiCellMigrate(integrated_helpers.ProviderUsageBaseTestCase):
# Now hard reboot the server in the source cell and it should go back
# to ACTIVE.
self.api.post_server_action(server['id'], {'reboot': {'type': 'HARD'}})
self._wait_for_state_change(server, 'ACTIVE')
self._reboot_server(server, hard=True)
# Now retry the resize without the fault in the target host to make
# sure things are OK (no duplicate entry errors in the target DB).
self.api.post_server_action(server['id'], body)
self._wait_for_state_change(server, 'VERIFY_RESIZE')
self._resize_server(server, flavor2)
def _assert_instance_not_in_cell(self, cell_name, server_id):
cell = self.cell_mappings[cell_name]
@ -1189,10 +1187,8 @@ class TestMultiCellMigrate(integrated_helpers.ProviderUsageBaseTestCase):
# Now hard reboot the server in the source cell and it should go back
# to ACTIVE.
self.api.post_server_action(server['id'], {'reboot': {'type': 'HARD'}})
self._wait_for_state_change(server, 'ACTIVE')
self._reboot_server(server, hard=True)
# Now retry the resize without the fault in the target host to make
# sure things are OK (no duplicate entry errors in the target DB).
self.api.post_server_action(server['id'], body)
self._wait_for_state_change(server, 'VERIFY_RESIZE')
self._resize_server(server, flavor2)

View File

@ -344,14 +344,7 @@ class ServersTest(integrated_helpers._IntegratedTestBase):
'SOFT_DELETED')
# Create a second server
server = self._build_server()
created_server2 = self.api.post_server({'server': server})
LOG.debug("created_server: %s", created_server2)
self.assertTrue(created_server2['id'])
# Wait for it to finish being created
self._wait_for_state_change(created_server2, 'ACTIVE')
self._create_server()
# Try to restore the first server, it should fail
ex = self.assertRaises(client.OpenStackApiException,
@ -8098,16 +8091,11 @@ class AcceleratorServerOpsTest(AcceleratorServerBase):
networks='none', expected_state='ACTIVE')
def test_soft_reboot_ok(self):
params = {'reboot': {'type': 'SOFT'}}
self.api.post_server_action(self.server['id'], params)
self._wait_for_state_change(self.server, 'ACTIVE')
self._reboot_server(self.server)
self._check_allocations_usage(self.server)
def test_hard_reboot_ok(self):
params = {'reboot': {'type': 'HARD'}}
self.api.post_server_action(self.server['id'], params)
self._wait_for_state_change(self.server, 'HARD_REBOOT')
self._wait_for_state_change(self.server, 'ACTIVE')
self._reboot_server(self.server, hard=True)
self._check_allocations_usage(self.server)
def test_pause_unpause_ok(self):

View File

@ -29,32 +29,25 @@ class InterfaceFullstack(integrated_helpers._IntegratedTestBase):
def test_detach_interface_negative_invalid_state(self):
# Create server with network
created_server = self._create_server(
server = self._create_server(
networks=[{'uuid': '3cb9bc59-5699-4588-a4b1-b87f96708bc6'}])
created_server_id = created_server['id']
found_server = self._wait_for_state_change(created_server, 'ACTIVE')
self.addCleanup(self._delete_server, server)
post = {
'interfaceAttachment': {
'net_id': "3cb9bc59-5699-4588-a4b1-b87f96708bc6"
}
}
self.api.attach_interface(created_server_id, post)
self.api.attach_interface(server['id'], post)
response = self.api.get_port_interfaces(created_server_id)[0]
port_id = response['port_id']
ports = self.api.get_port_interfaces(server['id'])
# Change status from ACTIVE to SUSPENDED for negative test
post = {'suspend': {}}
self.api.post_server_action(created_server_id, post)
found_server = self._wait_for_state_change(found_server, 'SUSPENDED')
server = self._suspend_server(server)
# Detach port interface in SUSPENDED (not ACTIVE, etc.)
ex = self.assertRaises(client.OpenStackApiException,
self.api.detach_interface,
created_server_id, port_id)
ex = self.assertRaises(
client.OpenStackApiException,
self.api.detach_interface,
server['id'], ports[0]['port_id'])
self.assertEqual(409, ex.response.status_code)
self.assertEqual('SUSPENDED', found_server['status'])
# Cleanup
self._delete_server(found_server)