Update Nova Server test

- test start
 - test stop
 - test start after stop
 - test delete
 - test with multiple images (CentOS, CirrOS, Fedora, Ubuntu...)

Change-Id: I3fd1d388a207724474068a8136c18657f92c3674
This commit is contained in:
Federico Ressi 2021-09-24 11:25:04 +02:00
parent e6658e2489
commit 4f6559e16d
4 changed files with 170 additions and 80 deletions

View File

@ -40,6 +40,7 @@ WaitForServerStatusError = _client.WaitForServerStatusError
WaitForServerStatusTimeout = _client.WaitForServerStatusTimeout WaitForServerStatusTimeout = _client.WaitForServerStatusTimeout
shutoff_server = _client.shutoff_server shutoff_server = _client.shutoff_server
activate_server = _client.activate_server activate_server = _client.activate_server
delete_server = _client.delete_server
ensure_server_status = _client.ensure_server_status ensure_server_status = _client.ensure_server_status
live_migrate_server = _client.live_migrate_server live_migrate_server = _client.live_migrate_server
migrate_server = _client.migrate_server migrate_server = _client.migrate_server

View File

@ -132,13 +132,22 @@ def get_server_id(server: typing.Optional[ServerType] = None,
return server_id return server_id
def get_server(server: typing.Optional[ServerType] = None, def get_server(server: ServerType = None,
server_id: typing.Optional[str] = None, server_id: str = None,
client: NovaClientType = None, **params) -> NovaServer: client: NovaClientType = None,
**params) -> NovaServer:
server_id = get_server_id(server=server, server_id=server_id) server_id = get_server_id(server=server, server_id=server_id)
return nova_client(client).servers.get(server_id, **params) return nova_client(client).servers.get(server_id, **params)
def delete_server(server: ServerType = None,
server_id: str = None,
client: NovaClientType = None,
**params):
server_id = get_server_id(server=server, server_id=server_id)
return nova_client(client).servers.delete(server_id, **params)
def migrate_server(server: typing.Optional[ServerType] = None, def migrate_server(server: typing.Optional[ServerType] = None,
server_id: typing.Optional[str] = None, server_id: typing.Optional[str] = None,
client: NovaClientType = None, **params): client: NovaClientType = None, **params):

View File

@ -79,6 +79,7 @@ FlavorStackFixture = _nova.FlavorStackFixture
ServerGroupStackFixture = _nova.ServerGroupStackFixture ServerGroupStackFixture = _nova.ServerGroupStackFixture
AffinityServerGroupStackFixture = _nova.AffinityServerGroupStackFixture AffinityServerGroupStackFixture = _nova.AffinityServerGroupStackFixture
AntiAffinityServerGroupStackFixture = _nova.AntiAffinityServerGroupStackFixture AntiAffinityServerGroupStackFixture = _nova.AntiAffinityServerGroupStackFixture
CloudInitServerStackFixture = _nova.CloudInitServerStackFixture
OctaviaLoadbalancerStackFixture = _octavia.OctaviaLoadbalancerStackFixture OctaviaLoadbalancerStackFixture = _octavia.OctaviaLoadbalancerStackFixture
OctaviaListenerStackFixture = _octavia.OctaviaListenerStackFixture OctaviaListenerStackFixture = _octavia.OctaviaListenerStackFixture

View File

@ -14,137 +14,216 @@
# under the License. # under the License.
from __future__ import absolute_import from __future__ import absolute_import
import abc
from oslo_log import log
import testtools import testtools
import tobiko import tobiko
from tobiko import config from tobiko import config
from tobiko.openstack import keystone from tobiko.openstack import keystone
from tobiko.openstack import neutron
from tobiko.openstack import nova from tobiko.openstack import nova
from tobiko.openstack import stacks from tobiko.openstack import stacks
from tobiko.openstack import tests
from tobiko.shell import ping from tobiko.shell import ping
class ServerStackResourcesTest(testtools.TestCase): LOG = log.getLogger(__name__)
stack = tobiko.required_setup_fixture(stacks.CirrosServerStackFixture)
def test_server(self):
"Test actual server details"
server = self.stack.resources.server
self.assertEqual('OS::Nova::Server', server.resource_type)
# Verify actual server status (is alive, etc.)
nova_client = nova.get_nova_client()
server_data = nova_client.servers.get(server.physical_resource_id)
self.assertEqual(self.stack.server_name, server_data.name)
def test_port(self):
"Test actual server port details"
port = self.stack.resources.port
self.assertEqual('OS::Neutron::Port', port.resource_type)
# Verify actual port status (is alive, etc.)
port_data = neutron.get_port(port.physical_resource_id)
self.assertEqual(port.physical_resource_id, port_data['id'])
@config.skip_if_prevent_create() class CirrosServerStackFixture(stacks.CirrosServerStackFixture):
class ServerCreationTest(testtools.TestCase):
def test_server_creation(self): def validate_created_stack(self):
tests.test_server_creation() stack = super().validate_created_stack()
self.assert_is_reachable()
def test_evacuable_server_creation(self): return stack
tests.test_evacuable_server_creation()
def test_server_creation_and_shutoff(self):
tests.test_server_creation_and_shutoff()
def test_servers_creation(self):
tests.test_servers_creation()
class MigrateServerStack(stacks.CirrosServerStackFixture):
pass
@keystone.skip_unless_has_keystone_credentials() @keystone.skip_unless_has_keystone_credentials()
@nova.skip_if_missing_hypervisors(count=2) class CirrosServerTest(testtools.TestCase):
class MigrateServerTest(testtools.TestCase):
stack = tobiko.required_setup_fixture(MigrateServerStack) stack = tobiko.required_fixture(CirrosServerStackFixture)
peer_stack = tobiko.required_setup_fixture(stacks.CirrosServerStackFixture) peer_stack = tobiko.required_fixture(stacks.CirrosServerStackFixture)
def test_migrate_server(self, live=False): def test_0_server_name(self):
server = self.ensure_server()
self.assertEqual(self.stack.server_name, server.name)
def test_1_activate_server(self):
self.ensure_server(status='ACTIVE')
self.assert_is_reachable()
@config.skip_if_prevent_create()
def test_2_delete_server(self):
server = self.ensure_server()
nova.delete_server(server)
for _ in tobiko.retry(timeout=60., interval=3.):
try:
server = nova.find_server(id=server.id)
except tobiko.ObjectNotFound:
LOG.debug(f"Server '{server.id}' deleted")
break
else:
LOG.debug(f"Waiting for server deletion:\n"
f" - server.id='{server.id}'"
f" - server.status='{server.status}'")
self.assert_is_unreachable()
@config.skip_if_prevent_create()
def test_3_create_server(self):
tobiko.cleanup_fixture(type(self).stack.fixture)
self.ensure_server(status='ACTIVE')
self.assert_is_reachable()
def test_4_shutoff_server(self):
self.ensure_server(status='SHUTOFF')
self.assert_is_unreachable()
def test_5_shutoff_and_activate_server(self):
self.ensure_server(status='SHUTOFF')
self.ensure_server(status='ACTIVE')
self.assert_is_reachable()
@nova.skip_if_missing_hypervisors(count=2)
def test_6_migrate_server(self, live=False):
"""Tests cold migration actually changes hypervisor """Tests cold migration actually changes hypervisor
""" """
server = self.setup_server() server = self.ensure_server(status='ACTIVE')
initial_hypervisor = nova.get_server_hypervisor(server) initial_hypervisor = nova.get_server_hypervisor(server)
server = self.migrate_server(server, live=live) server = self.migrate_server(server, live=live)
final_hypervisor = nova.get_server_hypervisor(server) final_hypervisor = nova.get_server_hypervisor(server)
self.assertNotEqual(initial_hypervisor, final_hypervisor) self.assertNotEqual(initial_hypervisor, final_hypervisor)
def test_migrate_server_with_host(self, live=False): @tobiko.skip("Expected to create problems on compute nodes")
def test_7_live_migrate_server(self):
self.test_6_migrate_server(live=True)
@nova.skip_if_missing_hypervisors(count=2)
def test_8_migrate_server_with_host(self, live=False):
"""Tests cold migration actually ends on target hypervisor """Tests cold migration actually ends on target hypervisor
""" """
server = self.setup_server() server = self.ensure_server(status='ACTIVE')
initial_hypervisor = nova.get_server_hypervisor(server) initial_hypervisor = nova.get_server_hypervisor(server)
for hypervisor in nova.list_hypervisors(status='enabled', state='up'): for hypervisor in nova.list_hypervisors(status='enabled', state='up'):
if initial_hypervisor != hypervisor.hypervisor_hostname: if initial_hypervisor != hypervisor.hypervisor_hostname:
target_hypervisor = hypervisor.hypervisor_hostname target_hypervisor = hypervisor.hypervisor_hostname
break break
else: else:
target_hypervisor = None tobiko.skip_test("Cannot find a valid hypervisor host to migrate "
self.skipTest("Cannot find a valid hypervisor host to migrate " "server to")
"server to")
server = self.migrate_server(server=server, host=target_hypervisor, server = self.migrate_server(server=server,
host=target_hypervisor,
live=live) live=live)
final_hypervisor = nova.get_server_hypervisor(server) final_hypervisor = nova.get_server_hypervisor(server)
self.assertNotEqual(initial_hypervisor, final_hypervisor)
self.assertEqual(target_hypervisor, final_hypervisor) self.assertEqual(target_hypervisor, final_hypervisor)
@tobiko.skip("Expected to create problems on compute nodes") @tobiko.skip("Expected to create problems on compute nodes")
def test_live_migrate_server(self): def test_8_live_migrate_server_with_host(self):
self.test_migrate_server(live=True) self.test_8_migrate_server_with_host(live=True)
@tobiko.skip("Expected to create problems on compute nodes") def ensure_server(self, status: str = None):
def test_live_migrate_server_with_host(self): server_id: str = self.stack.server_id
self.test_migrate_server_with_host(live=True) try:
server = nova.find_server(id=server_id, unique=True)
def setup_server(self): except tobiko.ObjectNotFound:
server = self.stack.ensure_server_status('ACTIVE') LOG.debug(f"Server '{server_id}' not found: recreate it...")
self.assertEqual('ACTIVE', server.status) server_id = tobiko.reset_fixture(self.stack).server_id
server = nova.find_server(id=server_id, unique=True)
LOG.debug(f"Server '{server_id}' created.")
if status not in [None, server.status]:
LOG.debug(f"Ensuring server '{server_id}' status changes:\
'{server.status}' -> '{status}'")
server = self.stack.ensure_server_status(status)
self.assertEqual(status, server.status)
return server return server
def migrate_server(self, server, live=False, **params): def migrate_server(self, server, live=False, **params):
self.assert_is_reachable()
self.assertEqual('ACTIVE', server.status) self.assertEqual('ACTIVE', server.status)
# wait until all VM fixed IPs are reachable
ping.assert_reachable_hosts(self.stack.list_fixed_ips(),
timeout=900.,
ssh_client=self.peer_stack.ssh_client)
if live: if live:
nova.live_migrate_server(server, **params) nova.live_migrate_server(server, **params)
server = nova.wait_for_server_status( server = nova.wait_for_server_status(
server, 'ACTIVE', transient_status=['MIGRATING']) server, 'ACTIVE', transient_status=['MIGRATING'])
else: else:
nova.migrate_server(server, **params) nova.migrate_server(server, **params)
server = nova.wait_for_server_status(server, 'VERIFY_RESIZE') server = nova.wait_for_server_status(server, 'VERIFY_RESIZE')
self.assertEqual('VERIFY_RESIZE', server.status) self.assertEqual('VERIFY_RESIZE', server.status)
nova.confirm_resize(server)
nova.confirm_resize(server)
server = nova.wait_for_server_status( server = nova.wait_for_server_status(
server, 'ACTIVE', transient_status=['VERIFY_RESIZE']) server, 'ACTIVE', transient_status=['VERIFY_RESIZE'])
self.assertEqual('ACTIVE', server.status) self.assert_is_reachable()
# wait until all VM fixed IPs are reachable
ping.assert_reachable_hosts(self.stack.list_fixed_ips(),
timeout=900.,
ssh_client=self.peer_stack.ssh_client)
# check floating IP is reachable
ping.assert_reachable_hosts([self.stack.floating_ip_address])
return server return server
def assert_is_reachable(self):
self.stack.assert_is_reachable()
ping.assert_reachable_hosts(self.stack.list_fixed_ips(),
timeout=300.,
ssh_client=self.peer_stack.ssh_client)
if self.stack.has_vlan:
self.stack.assert_vlan_is_reachable()
def assert_is_unreachable(self):
self.stack.assert_is_unreachable()
ping.assert_unreachable_hosts(self.stack.list_fixed_ips(),
timeout=300.,
ssh_client=self.peer_stack.ssh_client)
if self.stack.has_vlan:
self.stack.assert_vlan_is_unreachable()
class CloudInitServerStackFixture(stacks.CloudInitServerStackFixture,
abc.ABC):
def validate_created_stack(self):
stack = super().validate_created_stack()
self.wait_for_cloud_init_done()
self.assert_is_reachable()
return stack
class UbuntuMinimalServerStackFixture(CloudInitServerStackFixture,
stacks.UbuntuMinimalServerStackFixture):
pass
class UbuntuMinimalServerTest(CirrosServerTest):
stack = tobiko.required_fixture(UbuntuMinimalServerStackFixture)
class UbuntuServerStackFixture(CloudInitServerStackFixture,
stacks.UbuntuServerStackFixture):
pass
class UbuntuServerTest(CirrosServerTest):
stack = tobiko.required_fixture(UbuntuServerStackFixture)
class FedoraServerStackFixture(CloudInitServerStackFixture,
stacks.FedoraServerStackFixture):
pass
class FedoraServerTest(CirrosServerTest):
stack = tobiko.required_fixture(FedoraServerStackFixture)
class CentosServerStackFixture(CloudInitServerStackFixture,
stacks.CentosServerStackFixture):
pass
class CentosServerTest(CirrosServerTest):
stack = tobiko.required_fixture(CentosServerStackFixture)
class RedhatServerStackFixture(CloudInitServerStackFixture,
stacks.RedHatServerStackFixture):
pass
class RedhatServerTest(CirrosServerTest):
stack = tobiko.required_fixture(RedhatServerStackFixture)