Remove resource_setup skip checks

Removes resource_setup checks that were validating the number
of enabled compute nodes. It also removes the waiting for
compute nodes to set up. This is not part of the test class
resource configuration.
Test classes now only skip tests if the min_compute_nodes
is less than the required to run.
All tests that needs at least 1 compute node enabled
will now check and fail at the start of the test.
This patch also improves some action plan valiations that
were missing from some tests.

Change-Id: I7c13b78c362aa3041643fc78af4193e687db2bf4
Signed-off-by: Douglas Viroel <viroel@gmail.com>
This commit is contained in:
Douglas Viroel
2025-10-03 14:01:26 -03:00
parent 47ddf23d77
commit 10dc953872
12 changed files with 37 additions and 153 deletions

View File

@@ -66,6 +66,10 @@ class BaseInfraOptimScenarioTest(manager.ScenarioTest):
min_microversion = None
max_microversion = manager.LATEST_MICROVERSION
# Holds the initial configuration of available compute nodes, to assist
# the rollback procedure.
initial_compute_nodes_setup = []
# States where the object is waiting for some event to perform a transition
IDLE_STATES = ('RECOMMENDED', 'FAILED', 'SUCCEEDED', 'CANCELLED')
# States where the object can only be DELETED (end of its life-cycle)
@@ -266,6 +270,12 @@ class BaseInfraOptimScenarioTest(manager.ScenarioTest):
return all([ap['state'] in cls.AP_FINISHED_STATES
for ap in action_plans['action_plans']])
def check_min_enabled_compute_nodes(self, min_nodes):
enabled_compute_nodes = self.get_enabled_compute_nodes()
msg = ("This test required at least %s enabled compute nodes, but "
"only %s were found." % (min_nodes, len(enabled_compute_nodes)))
self.assertGreaterEqual(len(enabled_compute_nodes), min_nodes, msg=msg)
def wait_for_all_action_plans_to_finish(self):
assert test_utils.call_until_true(
func=self._are_all_action_plans_finished,

View File

@@ -45,19 +45,6 @@ class TestContinuousAudit(base.BaseInfraOptimScenarioTest):
if not CONF.compute_feature_enabled.live_migration:
raise cls.skipException("Live migration is not enabled")
@classmethod
def resource_setup(cls):
super().resource_setup()
enabled_compute_nodes = cls.get_enabled_compute_nodes()
cls.wait_for_compute_node_setup()
# NOTE(dviroel): If the class was not skipped and we don't have at
# least 2 compute nodes enabled, fail the test.
if len(enabled_compute_nodes) < 2:
cls.fail("At least 2 enabled compute nodes are required to run "
"continuous audit tests.")
@decorators.idempotent_id("bd6a18e9-bd51-4164-9e7f-4f19d9b428ba")
@decorators.attr(type=['strategy', 'zone_migration'])
def test_continuous_audit_zone_migration(self):
@@ -65,7 +52,7 @@ class TestContinuousAudit(base.BaseInfraOptimScenarioTest):
# NOTE(dviroel): We don't need to start/trigger the action plan to
# validate continous audits, but we need to create the workload and
# check if the strategy will get updates from the model.
self.check_min_enabled_compute_nodes(2)
self.addCleanup(self.wait_delete_instances_from_model)
src_host = self.get_enabled_compute_nodes()[0]['host']

View File

@@ -29,23 +29,17 @@ class TestDataModel(base.BaseInfraOptimScenarioTest):
min_microversion = "1.3"
@classmethod
def resource_setup(cls):
super(TestDataModel, cls).resource_setup()
def skip_checks(cls):
super().skip_checks()
if CONF.compute.min_compute_nodes < 1:
raise cls.skipException(
"Data model tests requires at least 1 compute node, "
"skipping tests.")
enabled_compute_nodes = cls.get_enabled_compute_nodes()
cls.wait_for_compute_node_setup()
if len(enabled_compute_nodes) < 1:
raise cls.skipException(
"Data model tests requires at least 1 enabled compute "
"node, skipping tests.")
@decorators.idempotent_id('dabd41a4-e668-43c8-89a2-3d231e2ed79d')
def test_data_model_with_instances(self):
# This test requires at least one enabled compute node
self.check_min_enabled_compute_nodes(1)
self.addCleanup(self.wait_delete_instances_from_model)
instances = self._create_one_instance_per_host()

View File

@@ -63,22 +63,14 @@ class TestExecuteActionsViaActuator(base.BaseInfraOptimScenarioTest):
]
@classmethod
def resource_setup(cls):
super(TestExecuteActionsViaActuator, cls).resource_setup()
def skip_checks(cls):
super().skip_checks()
if CONF.compute.min_compute_nodes < 2:
raise cls.skipException(
"Less than 2 compute nodes, skipping multinode tests.")
if not CONF.compute_feature_enabled.live_migration:
raise cls.skipException("Live migration is not enabled")
enabled_compute_nodes = cls.get_enabled_compute_nodes()
cls.wait_for_compute_node_setup()
if len(enabled_compute_nodes) < 2:
raise cls.skipException(
"Less than 2 compute nodes are enabled, "
"skipping multinode tests.")
def _get_flavors(self):
return self.mgr.flavors_client.list_flavors()['flavors']
@@ -200,6 +192,8 @@ class TestExecuteActionsViaActuator(base.BaseInfraOptimScenarioTest):
@decorators.idempotent_id('0af1a181-38c8-4416-8e85-8ebca8ac1cf8')
def test_execute_scenarios(self):
# Migration action requires at least 2 enabled compute nodes
self.check_min_enabled_compute_nodes(2)
self.addCleanup(self.rollback_compute_nodes_status)
for _, scenario in self.scenarios:

View File

@@ -43,19 +43,6 @@ class TestExecuteBasicStrategy(base.BaseInfraOptimScenarioTest):
if not CONF.compute_feature_enabled.live_migration:
raise cls.skipException("Live migration is not enabled")
@classmethod
def resource_setup(cls):
super(TestExecuteBasicStrategy, cls).resource_setup()
enabled_compute_nodes = cls.get_enabled_compute_nodes()
cls.wait_for_compute_node_setup()
if len(enabled_compute_nodes) < 2:
raise cls.skipException(
"Less than 2 compute nodes are enabled, "
"skipping multinode tests.")
@decorators.attr(type=['strategy', 'basic'])
@decorators.idempotent_id('62766a61-dfc4-478c-b80b-86d871227e67')
def test_execute_basic_strategy(self):
@@ -67,6 +54,7 @@ class TestExecuteBasicStrategy(base.BaseInfraOptimScenarioTest):
- run the action plan
- get results and make sure it succeeded
"""
self.check_min_enabled_compute_nodes(2)
self.addCleanup(self.rollback_compute_nodes_status)
self.addCleanup(self.wait_delete_instances_from_model)
self.addCleanup(self.clean_injected_metrics)

View File

@@ -44,23 +44,11 @@ class TestExecuteHostMaintenanceStrategy(base.BaseInfraOptimScenarioTest):
if not CONF.compute_feature_enabled.live_migration:
raise cls.skipException("Live migration is not enabled")
@classmethod
def resource_setup(cls):
super().resource_setup()
enabled_compute_nodes = cls.get_enabled_compute_nodes()
cls.wait_for_compute_node_setup()
if len(enabled_compute_nodes) < 2:
raise cls.skipException(
"Less than 2 compute nodes are enabled, "
"skipping multinode tests.")
@decorators.idempotent_id('17afd352-1929-46dd-a10a-63c90bb9255d')
@decorators.attr(type=['strategy', 'host_maintenance'])
def test_execute_host_maintenance_strategy(self):
# This test does not require metrics injection
self.check_min_enabled_compute_nodes(2)
self.addCleanup(self.rollback_compute_nodes_status)
self.addCleanup(self.wait_delete_instances_from_model)
instances = self._create_one_instance_per_host()
@@ -91,7 +79,7 @@ class TestExecuteHostMaintenanceStrategy(base.BaseInfraOptimScenarioTest):
@decorators.attr(type=['strategy', 'host_maintenance'])
def test_execute_host_maintenance_strategy_backup_node(self):
# This test does not require metrics injection
self.check_min_enabled_compute_nodes(2)
self.addCleanup(self.rollback_compute_nodes_status)
self.addCleanup(self.wait_delete_instances_from_model)
instances = self._create_one_instance_per_host()

View File

@@ -43,22 +43,11 @@ class TestExecuteNodeResourceConsolidationStrategy(
if not CONF.compute_feature_enabled.live_migration:
raise cls.skipException("Live migration is not enabled")
@classmethod
def resource_setup(cls):
super().resource_setup()
cls.wait_for_compute_node_setup()
enabled_compute_nodes = cls.get_enabled_compute_nodes()
if len(enabled_compute_nodes) < 2:
raise cls.skipException(
"Less than 2 compute nodes are enabled, "
"skipping multinode tests.")
@decorators.attr(type=['strategy', 'node_resource_consolidation'])
@decorators.idempotent_id('c0c061e9-4713-4a23-a6e1-5db794add685')
def test_execute_node_resource_consolidation_strategy_with_auto(self):
# This test does not require metrics injection
self.check_min_enabled_compute_nodes(2)
self.addCleanup(self.rollback_compute_nodes_status)
self.addCleanup(self.wait_delete_instances_from_model)
instances = self._create_one_instance_per_host()
@@ -77,7 +66,7 @@ class TestExecuteNodeResourceConsolidationStrategy(
audit_template['uuid'], **audit_kwargs)
action_plan, _ = self.get_action_plan_and_validate_actions(
audit['uuid'])
audit['uuid'], ['change_nova_service_state', 'migrate'])
if action_plan['state'] in ('SUPERSEDED', 'SUCCEEDED'):
# This means the action plan is superseded so we cannot trigger it,
@@ -90,7 +79,7 @@ class TestExecuteNodeResourceConsolidationStrategy(
@decorators.idempotent_id('12312f2b-ff7a-4722-9aa3-0262608e1ef0')
def test_execute_node_resource_consolidation_strategy_with_specify(self):
# This test does not require metrics injection
self.check_min_enabled_compute_nodes(2)
self.addCleanup(self.rollback_compute_nodes_status)
self.addCleanup(self.wait_delete_instances_from_model)
instances = self._create_one_instance_per_host()
@@ -109,7 +98,7 @@ class TestExecuteNodeResourceConsolidationStrategy(
audit_template['uuid'], **audit_kwargs)
action_plan, _ = self.get_action_plan_and_validate_actions(
audit['uuid'])
audit['uuid'], ['migrate'])
if action_plan['state'] in ('SUPERSEDED', 'SUCCEEDED'):
# This means the action plan is superseded so we cannot trigger it,

View File

@@ -53,22 +53,11 @@ class TestRealExecuteStrategies(base.BaseInfraOptimScenarioTest):
if not CONF.compute_feature_enabled.live_migration:
raise cls.skipException("Live migration is not enabled")
@classmethod
def resource_setup(cls):
super().resource_setup()
cls.wait_for_compute_node_setup()
enabled_compute_nodes = cls.get_enabled_compute_nodes()
if len(enabled_compute_nodes) < 2:
raise cls.skipException(
"Less than 2 compute nodes are enabled, "
"skipping multinode tests.")
@decorators.attr(type=['slow', 'real_load', 'cpu'])
@decorators.idempotent_id('672a7a4d-91a0-4753-a7a4-be28db8c1bfb')
def test_workload_balance_strategy_cpu(self):
# This test does not require metrics injection
self.addCleanup(self.rollback_compute_nodes_status)
self.check_min_enabled_compute_nodes(2)
self.addCleanup(self.wait_delete_instances_from_model)
host = self.get_enabled_compute_nodes()[0]['host']
hypervisor = self.get_hypervisor_details(host)
@@ -117,7 +106,7 @@ class TestRealExecuteStrategies(base.BaseInfraOptimScenarioTest):
@decorators.idempotent_id('f1b8a0c4-2d3e-4a5b-8f7c-6d9e5f2a0b1c')
def test_workload_balance_strategy_ram(self):
# This test does not require metrics injection
self.addCleanup(self.rollback_compute_nodes_status)
self.check_min_enabled_compute_nodes(2)
self.addCleanup(self.wait_delete_instances_from_model)
host = self.get_enabled_compute_nodes()[0]['host']
hypervisor = self.get_hypervisor_details(host)
@@ -164,8 +153,7 @@ class TestRealExecuteStrategies(base.BaseInfraOptimScenarioTest):
@decorators.attr(type=['slow', 'real_load'])
def test_workload_stabilization_strategy(self):
# This test does not require metrics injection
self.addCleanup(self.rollback_compute_nodes_status)
self.check_min_enabled_compute_nodes(2)
self.addCleanup(self.wait_delete_instances_from_model)
run_command = self.COMMANDS_CREATE_LOAD['instance_cpu_usage']
host = self.get_enabled_compute_nodes()[0]['host']

View File

@@ -43,19 +43,6 @@ class TestExecuteVmWorkloadBalanceStrategy(base.BaseInfraOptimScenarioTest):
if not CONF.compute_feature_enabled.live_migration:
raise cls.skipException("Live migration is not enabled")
@classmethod
def resource_setup(cls):
super().resource_setup()
enabled_compute_nodes = cls.get_enabled_compute_nodes()
cls.wait_for_compute_node_setup()
if len(enabled_compute_nodes) < 2:
raise cls.skipException(
"Less than 2 compute nodes are enabled, "
"skipping multinode tests.")
@decorators.attr(type=['strategy', 'vm_workload_consolidation'])
@decorators.idempotent_id('9f3ee978-e033-4c1e-bbf2-9e5a5cb8a365')
def test_execute_vm_workload_consolidation_strategy(self):
@@ -68,7 +55,7 @@ class TestExecuteVmWorkloadBalanceStrategy(base.BaseInfraOptimScenarioTest):
- get results and make sure it succeeded
"""
# This test requires metrics injection
self.check_min_enabled_compute_nodes(2)
self.addCleanup(self.rollback_compute_nodes_status)
self.addCleanup(self.wait_delete_instances_from_model)
self.addCleanup(self.clean_injected_metrics)
@@ -97,7 +84,7 @@ class TestExecuteVmWorkloadBalanceStrategy(base.BaseInfraOptimScenarioTest):
audit_template['uuid'], **audit_kwargs)
action_plan, _ = self.get_action_plan_and_validate_actions(
audit['uuid'])
audit['uuid'], ['change_nova_service_state', 'migrate'])
if action_plan['state'] in ('SUPERSEDED', 'SUCCEEDED'):
# This means the action plan is superseded so we cannot trigger it,

View File

@@ -44,23 +44,11 @@ class TestExecuteWorkloadBalanceStrategy(base.BaseInfraOptimScenarioTest):
if not CONF.compute_feature_enabled.live_migration:
raise cls.skipException("Live migration is not enabled")
@classmethod
def resource_setup(cls):
super().resource_setup()
enabled_compute_nodes = cls.get_enabled_compute_nodes()
cls.wait_for_compute_node_setup()
if len(enabled_compute_nodes) < 2:
raise cls.skipException(
"Less than 2 compute nodes are enabled, "
"skipping multinode tests.")
@decorators.attr(type=['strategy', 'workload_balance'])
@decorators.idempotent_id('64a9293f-0f81-431c-afae-ecabebae53f1')
def test_execute_workload_balance_strategy_cpu(self):
# This test requires metrics injection
self.addCleanup(self.rollback_compute_nodes_status)
self.check_min_enabled_compute_nodes(2)
self.addCleanup(self.wait_delete_instances_from_model)
self.addCleanup(self.clean_injected_metrics)
host = self.get_enabled_compute_nodes()[0]['host']
@@ -108,7 +96,7 @@ class TestExecuteWorkloadBalanceStrategy(base.BaseInfraOptimScenarioTest):
@decorators.idempotent_id('de4f662a-26b1-4cbe-ba8e-c213bac0a996')
def test_execute_workload_balance_strategy_ram(self):
# This test requires metrics injection
self.addCleanup(self.rollback_compute_nodes_status)
self.check_min_enabled_compute_nodes(2)
self.addCleanup(self.wait_delete_instances_from_model)
self.addCleanup(self.clean_injected_metrics)

View File

@@ -41,24 +41,11 @@ class TestExecuteWorkloadStabilizationStrategy(
if not CONF.compute_feature_enabled.live_migration:
raise cls.skipException("Live migration is not enabled")
@classmethod
def resource_setup(cls):
super().resource_setup()
enabled_compute_nodes = cls.get_enabled_compute_nodes()
cls.wait_for_compute_node_setup()
if len(enabled_compute_nodes) < 2:
raise cls.skipException(
"Less than 2 compute nodes are enabled, "
"skipping multinode tests.")
@decorators.attr(type=['strategy', 'workload_stabilization'])
@decorators.idempotent_id('14360d59-4923-49f7-bfe5-31d6a819b6f7')
def test_execute_workload_stabilization_strategy_cpu(self):
# This test requires metrics injection
self.addCleanup(self.rollback_compute_nodes_status)
self.check_min_enabled_compute_nodes(2)
self.addCleanup(self.wait_delete_instances_from_model)
self.addCleanup(self.clean_injected_metrics)
host = self.get_enabled_compute_nodes()[0]['host']
@@ -102,8 +89,7 @@ class TestExecuteWorkloadStabilizationStrategy(
@decorators.idempotent_id('4988b894-b237-4ebc-9af1-ecf1f9ea734e')
def test_execute_workload_stabilization_strategy_ram(self):
# This test requires metrics injection
self.addCleanup(self.rollback_compute_nodes_status)
self.check_min_enabled_compute_nodes(2)
self.addCleanup(self.wait_delete_instances_from_model)
self.addCleanup(self.clean_injected_metrics)
host = self.get_enabled_compute_nodes()[0]['host']

View File

@@ -43,18 +43,6 @@ class TestZoneMigrationStrategyBase(base.BaseInfraOptimScenarioTest):
if not CONF.compute_feature_enabled.live_migration:
raise cls.skipException("Live migration is not enabled")
@classmethod
def resource_setup(cls):
super().resource_setup()
enabled_compute_nodes = cls.get_enabled_compute_nodes()
cls.wait_for_compute_node_setup()
if len(enabled_compute_nodes) < 2:
raise cls.skipException(
"Less than 2 compute nodes are enabled, "
"skipping multinode tests.")
class TestExecuteZoneMigrationStrategy(TestZoneMigrationStrategyBase):
"""Tests for action plans"""
@@ -63,8 +51,7 @@ class TestExecuteZoneMigrationStrategy(TestZoneMigrationStrategyBase):
@decorators.attr(type=['strategy', 'zone_migration'])
def test_execute_zone_migration_with_destination_host(self):
# This test requires metrics injection
self.addCleanup(self.rollback_compute_nodes_status)
self.check_min_enabled_compute_nodes(2)
self.addCleanup(self.wait_delete_instances_from_model)
instances = self._create_one_instance_per_host()
# wait for compute model updates
@@ -96,8 +83,7 @@ class TestExecuteZoneMigrationStrategy(TestZoneMigrationStrategyBase):
@decorators.attr(type=['strategy', 'zone_migration'])
def test_execute_zone_migration_without_destination_host(self):
# This test requires metrics injection
self.addCleanup(self.rollback_compute_nodes_status)
self.check_min_enabled_compute_nodes(2)
self.addCleanup(self.wait_delete_instances_from_model)
instances = self._create_one_instance_per_host()
# wait for compute model updates
@@ -152,7 +138,6 @@ class TestExecuteZoneMigrationStrategyVolume(TestZoneMigrationStrategyBase):
@decorators.attr(type=['strategy', 'zone_migration', 'volume_migration'])
@decorators.idempotent_id('f8f4d551-d892-4111-ab92-5b6b5523e5dc')
def test_execute_zone_migration_volume_retype(self):
self.addCleanup(self.rollback_compute_nodes_status)
self.addCleanup(self.wait_delete_instances_from_model)
# create second volume type