From 18eb2c48284203e2c422eaf760f2677af717a47f Mon Sep 17 00:00:00 2001 From: Julia Kreger Date: Wed, 29 Nov 2023 08:40:30 -0800 Subject: [PATCH] Test multiple boot interfaces as part of one CI job The idea here came out of the 2024.1 PTG held in ?October? 2023, with the goal of being able to exercise testing of boot interfaces as a group in a single job, instead of spreading it out amongst CI jobs with different scenarios. That doesn't mean different scenarios are wrong, but as we add more boot interfaces as part of supporting HTTPBoot, we cannot double our scenarios. In theory, the hope is we should be able to consolidate down several secenario jobs into just one test running these jobs. Change-Id: Id41ee40c36624387216b2cfc1501f01a3217b2af --- .../scenario/baremetal_standalone_manager.py | 24 +++++- .../ironic_standalone/test_basic_ops.py | 85 +++++++++++++++++++ 2 files changed, 108 insertions(+), 1 deletion(-) diff --git a/ironic_tempest_plugin/tests/scenario/baremetal_standalone_manager.py b/ironic_tempest_plugin/tests/scenario/baremetal_standalone_manager.py index 1ad14859..f9435220 100644 --- a/ironic_tempest_plugin/tests/scenario/baremetal_standalone_manager.py +++ b/ironic_tempest_plugin/tests/scenario/baremetal_standalone_manager.py @@ -455,6 +455,21 @@ class BaremetalStandaloneScenarioTest(BaremetalStandaloneManager): # The node driver to use in the test driver = None + # If we do not require an explicit driver to be set as a base for + # the test. This is useful for tests where we perform a vertical + # slice of drivers to test as opposed to focusing all testing + # around the driver itself. This allows for us to verify the + # driver interfaces align with the established contracts, + # and allows the same test to use ipmi, redfish, or some other + # known driver to work. + use_available_driver = None + + # If we don't require an explicit driver, then what drivers *can* we + # operate with. In essence, this exists to prevent the test from failing + # on 3rd party drivers, and vendor specific driers which do not support + # the sort of itnerfaces we may be trying to test by default. + valid_driver_list = [] + # The bios interface to use by the HW type. The bios interface of the # node used in the test will be set to this value. If set to None, the # node will retain its existing bios_interface value (which may have been @@ -511,7 +526,8 @@ class BaremetalStandaloneScenarioTest(BaremetalStandaloneManager): @classmethod def skip_checks(cls): super(BaremetalStandaloneScenarioTest, cls).skip_checks() - if (cls.driver not in CONF.baremetal.enabled_drivers + if (not cls.use_available_driver + and cls.driver not in CONF.baremetal.enabled_drivers + CONF.baremetal.enabled_hardware_types): raise cls.skipException( 'The driver: %(driver)s used in test is not in the list of ' @@ -619,6 +635,12 @@ class BaremetalStandaloneScenarioTest(BaremetalStandaloneManager): # just get an available node cls.node = cls.get_and_reserve_node() + if (cls.use_available_driver + and not cls.driver + and cls.node['driver'] in cls.valid_driver_list): + # If we're attempting to re-use the existing driver, then + # lets save a value for update_node_driver to work with. + cls.driver = cls.node['driver'] cls.update_node_driver(cls.node['uuid'], cls.driver, **boot_kwargs) @classmethod 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 fcb37460..453ccfac 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 @@ -700,3 +700,88 @@ class BaremetalRedfishIPxeAnacondaNoGlance( kernel_ref=CONF.baremetal.anaconda_kernel_ref, ramdisk_ref=CONF.baremetal.anaconda_initial_ramdisk_ref, stage2_ref=CONF.baremetal.anaconda_stage2_ramdisk_ref) + + +class BaremetalChangeBaseBootInterface( + bsm.BaremetalStandaloneScenarioTest): + + # NOTE(TheJulia): The resource setup class *already* auto-sets the + # requested boot interface. We just never tried to articulate + # this sort of configuration before this class. + # The goal: Test as many boot interfaces to ensure they are functional + # under the base context + + api_microversion = '1.31' # to set the boot_interface + driver = None + # This is intentionally meant to be a relatively light weight test, + # but one that covers the common cases, i.e. direct is most appropriate + # here. Ramdisk/anaconda/ansible and friends are all more specific + # cased. + deploy_interface = 'direct' + image_ref = CONF.baremetal.whole_disk_image_url + image_checksum = CONF.baremetal.whole_disk_image_checksum + wholedisk_image = True + + # This is a special override which allows us to just use the base + # driver interface defined on the node, and not have to special case it + # and focus on the "driver". + use_available_driver = True + + # List of valid drivers which these tests *can* attempt to utilize. + # Generally these should be the most commom, stock, upstream drivers. + valid_driver_list = ['ipmi', 'redfish'] + + # Bypass secondary attribute presence check as these tests don't require + # the driver to be set. + mandatory_attr = ['image_ref'] + + +class BaremetalPXEBootTestClass(BaremetalChangeBaseBootInterface): + + boot_interface = 'pxe' + + @decorators.idempotent_id('62c12d2c-8c9f-4526-b9ab-b9cd63e0ea8a') + @utils.services('network') + def test_ip_access_to_server(self): + self.boot_and_verify_node() + + +class BaremetalIPXEBootTestClass(BaremetalChangeBaseBootInterface): + + boot_interface = 'ipxe' + + @decorators.idempotent_id('113acd0a-9872-4631-b3ee-54da7e3bb262') + @utils.services('network') + def test_ip_access_to_server(self): + self.boot_and_verify_node() + + +class BaremetalHTTPBootTestClass(BaremetalChangeBaseBootInterface): + + boot_interface = 'http' + + @decorators.idempotent_id('782c43db-77a1-4a3a-b46e-0ce9cbb7fba5') + @utils.services('network') + def test_ip_access_to_server(self): + self.boot_and_verify_node() + + +class BaremetalHttpIPXEBootTestClass(BaremetalChangeBaseBootInterface): + + boot_interface = 'http-ipxe' + + @decorators.idempotent_id('45400d8e-55a5-4ba6-81f5-935a4183ed90') + @utils.services('network') + def test_ip_access_to_server(self): + self.boot_and_verify_node() + + +class BaremetalRedfishVmediaBootTestClass(BaremetalChangeBaseBootInterface): + + boot_interface = 'redfish-virtual-media' + driver = 'redfish' + + @decorators.idempotent_id('10535270-27e5-4616-9013-9507b1960dfa') + @utils.services('network') + def test_ip_access_to_server(self): + self.boot_and_verify_node()