Rescue mode tempest tests
- Adds scenario test for rescue mode.
- Removes redundant call to validate_authentication() in
existing test code due to it is called within get_remote_client.
Partial-Bug: 1526449
Depends-On: I7c20a0c5f566c3255350fd494d1a2cde84a99440
Change-Id: I6b62724711ddbe17b59dad30283e544272d9c1f3
Co-Authored-By: Mario Villaplana <mario.villaplana@gmail.com>
Co-Authored-By: Annie Lezil <annie.lezil@gmail.com>
diff --git a/ironic_tempest_plugin/config.py b/ironic_tempest_plugin/config.py
index 3594b5b..c4fb185 100644
--- a/ironic_tempest_plugin/config.py
+++ b/ironic_tempest_plugin/config.py
@@ -129,6 +129,8 @@
cfg.ListOpt('enabled_rescue_interfaces',
default=['no-rescue'],
help="List of Ironic enabled rescue interfaces."),
+ cfg.StrOpt('default_rescue_interface',
+ help="Ironic default rescue interface."),
cfg.IntOpt('adjusted_root_disk_size_gb',
min=0,
help="Ironic adjusted disk size to use in the standalone tests "
diff --git a/ironic_tempest_plugin/tests/scenario/baremetal_manager.py b/ironic_tempest_plugin/tests/scenario/baremetal_manager.py
index c220619..6d7d55b 100644
--- a/ironic_tempest_plugin/tests/scenario/baremetal_manager.py
+++ b/ironic_tempest_plugin/tests/scenario/baremetal_manager.py
@@ -19,6 +19,7 @@
from tempest.common import waiters
from tempest import config
from tempest.lib.common import api_version_utils
+from tempest.lib.common.utils.linux import remote_client
from tempest.lib import exceptions as lib_exc
from ironic_tempest_plugin import clients
@@ -232,3 +233,44 @@
BaremetalProvisionStates.AVAILABLE],
timeout=CONF.baremetal.unprovision_timeout,
interval=30)
+
+ def rescue_instance(self, instance, node, server_ip,
+ servers_client=None):
+ """Rescue the instance, verify we can ping and SSH."""
+ if servers_client is None:
+ servers_client = self.servers_client
+
+ rescuing_instance = servers_client.rescue_server(instance['id'])
+ rescue_password = rescuing_instance['adminPass']
+
+ self.wait_provisioning_state(
+ node['uuid'],
+ BaremetalProvisionStates.RESCUE,
+ timeout=CONF.baremetal.rescue_timeout)
+ waiters.wait_for_server_status(servers_client,
+ instance['id'], 'RESCUE')
+ # Ping server ip
+ self.assertTrue(self.ping_ip_address(server_ip))
+ # Open ssh connection to server
+ linux_client = remote_client.RemoteClient(
+ server_ip,
+ 'rescue',
+ password=rescue_password,
+ server=self.instance,
+ servers_client=servers_client,
+ ssh_timeout=CONF.baremetal.rescue_timeout)
+ linux_client.validate_authentication()
+
+ def unrescue_instance(self, instance, node, server_ip,
+ servers_client=None):
+ if servers_client is None:
+ servers_client = self.servers_client
+ self.servers_client.unrescue_server(instance['id'])
+ self.wait_provisioning_state(
+ node['uuid'],
+ BaremetalProvisionStates.ACTIVE,
+ timeout=CONF.baremetal.unrescue_timeout)
+ waiters.wait_for_server_status(servers_client,
+ instance['id'], 'ACTIVE')
+ # Verify server connection
+ self.get_remote_client(server_ip)
diff --git a/ironic_tempest_plugin/tests/scenario/test_baremetal_basic_ops.py b/ironic_tempest_plugin/tests/scenario/test_baremetal_basic_ops.py
index f78155d..61e5323 100644
--- a/ironic_tempest_plugin/tests/scenario/test_baremetal_basic_ops.py
+++ b/ironic_tempest_plugin/tests/scenario/test_baremetal_basic_ops.py
@@ -45,6 +45,26 @@
expected state transitions
"""
+ TEST_RESCUE_MODE = False
+
+ @classmethod
+ def skip_checks(cls):
+ super(BaremetalBasicOps, cls).skip_checks()
+
+ # If default rescue interface is configured to test the rescue
+ # feature, then skips this test and let the test derived class
+ # to be executed.
+ rescue_if = CONF.baremetal.default_rescue_interface
+ if cls.TEST_RESCUE_MODE:
+ if not rescue_if or rescue_if == 'no-rescue':
+ msg = 'Node rescue interface is not enabled.'
+ raise cls.skipException(msg)
+ else:
+ if rescue_if and rescue_if != 'no-rescue':
+ msg = ('Node rescue interface is enabled, but %s class '
+ 'cannot test rescue operations.' % cls.__name__)
+ raise cls.skipException(msg)
+
@staticmethod
def _is_version_supported(version):
"""Return whether an API microversion is supported."""
@@ -193,7 +213,6 @@
self.validate_ports()
self.validate_scheduling()
ip_address = self.get_server_ip(self.instance)
- self.get_remote_client(ip_address).validate_authentication()
vm_client = self.get_remote_client(ip_address)
# We expect the ephemeral partition to be mounted on /mnt and to have
@@ -205,4 +224,15 @@
self.create_timestamp(
ip_address, private_key=self.keypair['private_key'])
+ # Test rescue mode
+ if self.TEST_RESCUE_MODE:
+ self.rescue_instance(self.instance, self.node, ip_address)
+ self.unrescue_instance(self.instance, self.node, ip_address)
+
self.terminate_instance(self.instance)
+
+
+class BaremetalBasicOpsAndRescue(BaremetalBasicOps):
+ """This test includes rescue/unrescue ops."""
+
+ TEST_RESCUE_MODE = True