Merge "Add stable/2026.1 job"
diff --git a/ironic_tempest_plugin/config.py b/ironic_tempest_plugin/config.py
index 38a67eb..b0f44d2 100644
--- a/ironic_tempest_plugin/config.py
+++ b/ironic_tempest_plugin/config.py
@@ -193,6 +193,9 @@
cfg.ListOpt('enabled_bios_interfaces',
default=['fake'],
help="List of Ironic enabled bios interfaces."),
+ cfg.ListOpt('enabled_console_interfaces',
+ default=['fake', 'no-console'],
+ help="List of Ironic enabled console interfaces."),
cfg.ListOpt('enabled_deploy_interfaces',
default=['iscsi', 'direct'],
help="List of Ironic enabled deploy interfaces."),
diff --git a/ironic_tempest_plugin/services/baremetal/v1/json/baremetal_client.py b/ironic_tempest_plugin/services/baremetal/v1/json/baremetal_client.py
index d12ece4..3a7e35d 100644
--- a/ironic_tempest_plugin/services/baremetal/v1/json/baremetal_client.py
+++ b/ironic_tempest_plugin/services/baremetal/v1/json/baremetal_client.py
@@ -299,12 +299,13 @@
"""
node = {}
- # Explicitly allow definition of network interface and deploy
- # interface to allow tests to specify the required values
- # as they hold a great deal of logic which is executed upon and
- # they can ultimately impact test behavior.
+ # Explicitly allow definition of network interface, deploy
+ # interface, and console interface to allow tests to specify
+ # the required values as they hold a great deal of logic which
+ # is executed upon and they can ultimately impact test behavior.
for field in ('resource_class', 'name', 'description', 'shard',
- 'network_interface', 'deploy_interface'):
+ 'network_interface', 'deploy_interface',
+ 'console_interface'):
if kwargs.get(field):
node[field] = kwargs[field]
diff --git a/ironic_tempest_plugin/tests/api/admin/test_nodes.py b/ironic_tempest_plugin/tests/api/admin/test_nodes.py
index 0d82577..27d87cf 100644
--- a/ironic_tempest_plugin/tests/api/admin/test_nodes.py
+++ b/ironic_tempest_plugin/tests/api/admin/test_nodes.py
@@ -10,7 +10,9 @@
# License for the specific language governing permissions and limitations
# under the License.
+
from oslo_utils import uuidutils
+from tempest.common import compute
from tempest import config
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
@@ -1319,3 +1321,47 @@
def test_create_node_with_description(self):
_, body = self.create_node(self.chassis['uuid'], description='meow')
self.assertEqual('meow', body['description'])
+
+
+class TestNodeGraphicalConsole(base.BaseBaremetalTest,
+ compute.NoVNCValidateMixin):
+ """Tests for fake-graphical console connection."""
+
+ min_microversion = '1.96'
+
+ @classmethod
+ def skip_checks(cls):
+ super(TestNodeGraphicalConsole, cls).skip_checks()
+ if CONF.baremetal.driver != 'fake-hardware':
+ raise cls.skipException('These tests rely on fake-hardware')
+ if 'fake-graphical' not in CONF.baremetal.enabled_console_interfaces:
+ raise cls.skipException('These tests rely on fake-graphical being'
+ 'included in enabled_console_interfaces')
+
+ def setUp(self):
+ super(TestNodeGraphicalConsole, self).setUp()
+
+ _, self.chassis = self.create_chassis()
+ _, self.node = self.create_node(self.chassis['uuid'],
+ console_interface="fake-graphical")
+
+ @decorators.idempotent_id('80504575-9b21-4670-92d1-143b948f9437')
+ def test_graphical_console_connection(self):
+ self.client.set_console_mode(self.node['uuid'], True)
+ waiters.wait_for_bm_node_status(self.client, self.node['uuid'],
+ 'console_enabled', True)
+ self.addCleanup(self.client.set_console_mode, self.node['uuid'],
+ False)
+
+ _, body = self.client.get_console(self.node['uuid'])
+ console_info = body['console_info']
+ self.assertEqual('vnc', console_info['type'])
+ # Do the initial HTTP Request to novncproxy to get the NoVNC JavaScript
+ self.validate_novnc_html(console_info['url'])
+ # Do the WebSockify HTTP Request to novncproxy to do the RFB connection
+ self.websocket = compute.create_websocket(console_info['url'])
+ self.addCleanup(self.websocket.close)
+ # Validate that we successfully connected and upgraded to Web Sockets
+ self.validate_websocket_upgrade()
+ # Validate the RFB Negotiation to determine if a valid VNC session
+ self.validate_rfb_negotiation()
diff --git a/ironic_tempest_plugin/tests/scenario/ironic_standalone/test_basic_ops.py b/ironic_tempest_plugin/tests/scenario/ironic_standalone/test_basic_ops.py
index 09da6d3..63aa0ed 100644
--- a/ironic_tempest_plugin/tests/scenario/ironic_standalone/test_basic_ops.py
+++ b/ironic_tempest_plugin/tests/scenario/ironic_standalone/test_basic_ops.py
@@ -423,18 +423,6 @@
self.boot_and_verify_node()
-class BaremetalIdracWSManDirectIPxeWholedisk(
- BaremetalIdracDirectIPxeWholedisk):
- power_interface = 'idrac-wsman'
- management_interface = 'idrac-wsman'
-
-
-class BaremetalIdracWSManDirectPxeWholedisk(
- BaremetalIdracDirectPxeWholedisk):
- power_interface = 'idrac-wsman'
- management_interface = 'idrac-wsman'
-
-
class BaremetalIdracRedfishDirectIPxeWholedisk(
BaremetalIdracDirectIPxeWholedisk):
diff --git a/ironic_tempest_plugin/tests/scenario/ironic_standalone/test_bios.py b/ironic_tempest_plugin/tests/scenario/ironic_standalone/test_bios.py
index ca63292..74efaba 100644
--- a/ironic_tempest_plugin/tests/scenario/ironic_standalone/test_bios.py
+++ b/ironic_tempest_plugin/tests/scenario/ironic_standalone/test_bios.py
@@ -125,8 +125,3 @@
class BaremetalIdracRedfishBios(
BaremetalIdracBiosCleaning):
bios_interface = 'idrac-redfish'
-
-
-class BaremetalIdracWSManBios(
- BaremetalIdracBiosCleaning):
- bios_interface = 'idrac-wsman'
diff --git a/ironic_tempest_plugin/tests/scenario/ironic_standalone/test_cleaning.py b/ironic_tempest_plugin/tests/scenario/ironic_standalone/test_cleaning.py
index a18f8e9..519eea6 100644
--- a/ironic_tempest_plugin/tests/scenario/ironic_standalone/test_cleaning.py
+++ b/ironic_tempest_plugin/tests/scenario/ironic_standalone/test_cleaning.py
@@ -198,13 +198,6 @@
power_interface = 'idrac-redfish'
-class BaremetalIdracWSManManagementCleaning(
- BaremetalIdracManagementCleaning):
-
- management_interface = 'idrac-wsman'
- power_interface = 'idrac-wsman'
-
-
class BaremetalIdracRaidCleaning(bsm.BaremetalStandaloneScenarioTest):
mandatory_attr = ['driver', 'raid_interface']
@@ -319,11 +312,6 @@
raid_interface = 'idrac-redfish'
-class BaremetalIdracWSManRaidCleaning(
- BaremetalIdracRaidCleaning):
- raid_interface = 'idrac-wsman'
-
-
class BaremetalRedfishFirmwareUpdate(bsm.BaremetalStandaloneScenarioTest):
api_microversion = '1.68' # to support redfish firmware update
diff --git a/ironic_tempest_plugin/tests/scenario/ironic_standalone/test_inspection_basic.py b/ironic_tempest_plugin/tests/scenario/ironic_standalone/test_inspection_basic.py
index 7d1d602..98f1b64 100644
--- a/ironic_tempest_plugin/tests/scenario/ironic_standalone/test_inspection_basic.py
+++ b/ironic_tempest_plugin/tests/scenario/ironic_standalone/test_inspection_basic.py
@@ -139,7 +139,3 @@
class BaremetalIdracRedfishInspect(BaremetalIdracInspect):
inspect_interface = 'idrac-redfish'
-
-
-class BaremetalIdracWSManInspect(BaremetalIdracInspect):
- inspect_interface = 'idrac-wsman'
diff --git a/ironic_tempest_plugin/tests/scenario/test_baremetal_multitenancy.py b/ironic_tempest_plugin/tests/scenario/test_baremetal_multitenancy.py
index 5bb7df5..4a8db41 100644
--- a/ironic_tempest_plugin/tests/scenario/test_baremetal_multitenancy.py
+++ b/ironic_tempest_plugin/tests/scenario/test_baremetal_multitenancy.py
@@ -174,7 +174,13 @@
@decorators.idempotent_id('26e2f145-2a8e-4dc7-8457-7f2eb2c6749d')
@utils.services('compute', 'image', 'network')
def test_baremetal_multitenancy(self):
- self.multitenancy_check()
+ if CONF.service_available.nova:
+ # If nova is not present, run the test, otherwise
+ # skip the test in order to not duplicate test execution.
+ self.skipTest('Compute service is present, skipping this test '
+ 'to avoid duplication.')
+ else:
+ self.multitenancy_check()
@decorators.idempotent_id('9e38631a-2df2-11e9-810e-8c16450ea513')
@utils.services('compute', 'image', 'network')
diff --git a/ironic_tempest_plugin/tests/scenario/test_introspection_basic.py b/ironic_tempest_plugin/tests/scenario/test_introspection_basic.py
index 44b8f98..918eea8 100644
--- a/ironic_tempest_plugin/tests/scenario/test_introspection_basic.py
+++ b/ironic_tempest_plugin/tests/scenario/test_introspection_basic.py
@@ -22,19 +22,21 @@
def verify_node_introspection_data(self, node):
data = self.introspection_data(node['uuid'])
- self.assertEqual(data['cpu_arch'],
- self.flavor['properties']['cpu_arch'])
+ # Validate that introspection discovered CPU architecture
+ # (common architectures supported by Ironic)
+ self.assertIn(data['cpu_arch'],
+ ['x86_64', 'i386', 'aarch64', 'ppc64', 'ppc64le'])
self.assertGreater(int(data['memory_mb']), 0)
self.assertGreater(int(data['cpus']), 0)
def verify_node_flavor(self, node):
- expected_cpu_arch = self.flavor['properties']['cpu_arch']
-
+ # Validate that introspection populated node properties correctly
self.assertGreater(int(node['properties']['cpus']), 0)
self.assertGreater(int(node['properties']['memory_mb']), 0)
self.assertGreater(int(node['properties']['local_gb']), 0)
- self.assertEqual(expected_cpu_arch,
- node['properties']['cpu_arch'])
+ # Validate cpu_arch was discovered and is a known architecture
+ self.assertIn(node['properties']['cpu_arch'],
+ ['x86_64', 'i386', 'aarch64', 'ppc64', 'ppc64le'])
def verify_introspection_aborted(self, uuid):
status = self.introspection_status(uuid)
@@ -53,7 +55,6 @@
def test_baremetal_introspection(self):
"""This smoke test case follows this set of operations:
- * Fetches expected properties from baremetal flavor
* Removes all properties from nodes
* Sets nodes to manageable state
* Imports introspection rule basic_ops_rule.json