Add support for microversion testing for api and scenario tests

Following the tempest guide[1] for implementing microversion tests,
a couple of changes were made in the plugin to better adapt it to support
new test classes for different microversions. When not defined a minimum
microversion, the min microversion from the service will be used.
This change only affects the api and scenarios tests, since the
client_functional tests have their own way to setup the api version,
which can be further improved if needed.
Some test classes had to set a minimum api version due to helper functions
like the use of `GET /v1/data_model`.
Two new configuration options were added to define the test target
microversions, and should be used to help on testing stable branches
in future releases.

[1] https://docs.openstack.org/tempest/latest/microversion_testing.html#how-to-implement-microversion-tests

Depends-On: https://review.opendev.org/c/openstack/watcher/+/956380

Change-Id: Id8fa25593b5cd47f5943b228415cd191e41e19ab
Signed-off-by: Douglas Viroel <viroel@gmail.com>
This commit is contained in:
Douglas Viroel
2025-07-31 17:54:40 -03:00
parent 6d2a858aec
commit abd34b8a1a
13 changed files with 118 additions and 2 deletions

View File

@@ -115,4 +115,16 @@ OptimizationGroup = [
help="In real-data test cases, the period of time during which "
"the load will be executed in seconds."
),
cfg.StrOpt(
"min_microversion",
default=None,
help="Lower version of the test target microversion range. "
"The format is 'X.Y', where 'X' and 'Y' are int values."
),
cfg.StrOpt(
"max_microversion",
default=None,
help="Upper version of the test target microversion range. "
"The format is 'X.Y', where 'X' and 'Y' are int values."
),
]

View File

@@ -0,0 +1,47 @@
# Copyright 2025 Red Hat, Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import fixtures
from watcher_tempest_plugin.services.infra_optim.v1.json import client
class APIMicroversionFixture(fixtures.Fixture):
"""API Microversion Fixture to set service microversion.
This class provides the fixture to set and reset the microversion
on service client. Service client has global variable to set the
microversion for that service API request.
This class can be used with useFixture: Example::
def setUp(self):
super(BaseInfraOptimTest, self).setUp()
self.useFixture(api_microversion_fixture.APIMicroversionFixture(
optimize_microversion=self.request_microversion))
This class only supports the Resource Optimization service.
:param str optimize_microversion: microvesion to be set on resource
optimization service client
"""
def __init__(self, optimize_microversion):
self.optimize_microversion = optimize_microversion
def _setUp(self):
super(APIMicroversionFixture, self)._setUp()
client.INFRA_OPTIM_VERSION = self.optimize_microversion
self.addCleanup(self._reset_optimize_microversion)
def _reset_optimize_microversion(self):
client.INFRA_OPTIM_VERSION = None

View File

@@ -19,7 +19,7 @@ from oslo_utils import uuidutils
from watcher_tempest_plugin.services import base
INFRA_OPTIM_VERSION = '1.4'
INFRA_OPTIM_VERSION = None
class InfraOptimClientJSON(base.BaseClient):

View File

@@ -18,16 +18,21 @@ import functools
import time
from tempest import config
from tempest.lib.common import api_version_utils
from tempest.lib.common.utils import data_utils
from tempest.lib.common.utils import test_utils
from tempest import test
from watcher_tempest_plugin import infra_optim_clients as clients
from watcher_tempest_plugin.services.infra_optim.v1.json import (
api_microversion_fixture
)
CONF = config.CONF
class BaseInfraOptimTest(test.BaseTestCase):
class BaseInfraOptimTest(api_version_utils.BaseMicroversionTest,
test.BaseTestCase):
"""Base class for Infrastructure Optimization API tests."""
# States where the object is waiting for some event to perform a transition
@@ -48,6 +53,12 @@ class BaseInfraOptimTest(test.BaseTestCase):
if not CONF.service_available.watcher:
raise cls.skipException('Watcher support is required')
api_version_utils.check_skip_with_microversion(
cls.min_microversion,
cls.max_microversion,
CONF.optimize.min_microversion,
CONF.optimize.max_microversion)
@classmethod
def setup_credentials(cls):
super(BaseInfraOptimTest, cls).setup_credentials()
@@ -59,6 +70,11 @@ class BaseInfraOptimTest(test.BaseTestCase):
cls.client = cls.mgr.io_client
cls.gnocchi = cls.mgr.gn_client
def setUp(self):
super(BaseInfraOptimTest, self).setUp()
self.useFixture(api_microversion_fixture.APIMicroversionFixture(
optimize_microversion=self.request_microversion))
@classmethod
def resource_setup(cls):
super(BaseInfraOptimTest, cls).resource_setup()
@@ -71,6 +87,11 @@ class BaseInfraOptimTest(test.BaseTestCase):
# action plans to delete (including potential orphan one(s))
cls.created_action_plans_audit_uuids = set()
cls.request_microversion = (
api_version_utils.select_request_microversion(
cls.min_microversion,
CONF.optimize.min_microversion))
@classmethod
def resource_cleanup(cls):
"""Ensure that all created objects get destroyed."""

View File

@@ -32,12 +32,16 @@ from oslo_log import log
from tempest.common import waiters
from tempest import config
from tempest.lib.common import api_microversion_fixture
from tempest.lib.common import api_version_utils
from tempest.lib.common.utils import data_utils
from tempest.lib.common.utils import test_utils
from tempest.lib import exceptions
from tempest.scenario import manager
from watcher_tempest_plugin import infra_optim_clients as clients
from watcher_tempest_plugin.services.infra_optim.v1.json import (
api_microversion_fixture as watcher_microversion_fixture
)
LOG = log.getLogger(__name__)
@@ -54,6 +58,9 @@ NOVA_API_VERSION_CREATE_WITH_HOST = '2.74'
class BaseInfraOptimScenarioTest(manager.ScenarioTest):
"""Base class for Infrastructure Optimization API tests."""
min_microversion = None
max_microversion = manager.LATEST_MICROVERSION
# 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)
@@ -91,6 +98,12 @@ class BaseInfraOptimScenarioTest(manager.ScenarioTest):
if not CONF.service_available.watcher:
raise cls.skipException('Watcher support is required')
api_version_utils.check_skip_with_microversion(
cls.min_microversion,
cls.max_microversion,
CONF.optimize.min_microversion,
CONF.optimize.max_microversion)
@classmethod
def setup_credentials(cls):
cls._check_network_config()
@@ -111,11 +124,18 @@ class BaseInfraOptimScenarioTest(manager.ScenarioTest):
compute_microversion=self.compute_request_microversion))
self.useFixture(api_microversion_fixture.APIMicroversionFixture(
placement_microversion=CONF.placement.min_microversion))
self.useFixture(watcher_microversion_fixture.APIMicroversionFixture(
optimize_microversion=self.request_microversion))
@classmethod
def resource_setup(cls):
super(BaseInfraOptimScenarioTest, cls).resource_setup()
cls.request_microversion = (
api_version_utils.select_request_microversion(
cls.min_microversion,
CONF.optimize.min_microversion))
@classmethod
def resource_cleanup(cls):
"""Ensure that all created objects get destroyed."""

View File

@@ -29,6 +29,8 @@ CONF = config.CONF
class TestExecuteBasicStrategy(base.BaseInfraOptimScenarioTest):
"""Tests for action plans"""
# Minimal version required for list data models
min_microversion = "1.3"
# Minimal version required for _create_one_instance_per_host
compute_min_microversion = base.NOVA_API_VERSION_CREATE_WITH_HOST

View File

@@ -27,6 +27,8 @@ LOG = log.getLogger(__name__)
class TestExecuteHostMaintenanceStrategy(base.BaseInfraOptimScenarioTest):
"""Tests for host_maintenance"""
# Minimal version required for list data models
min_microversion = "1.3"
# Minimal version required for _create_one_instance_per_host
compute_min_microversion = base.NOVA_API_VERSION_CREATE_WITH_HOST

View File

@@ -26,6 +26,8 @@ CONF = config.CONF
class TestExecuteStrategies(base.BaseInfraOptimScenarioTest):
"""Tests for strategies"""
# Minimal version required for list data models
min_microversion = "1.3"
# Minimal version required for _create_one_instance_per_host
compute_min_microversion = base.NOVA_API_VERSION_CREATE_WITH_HOST

View File

@@ -26,6 +26,8 @@ LOG = log.getLogger(__name__)
class TestRealExecuteStrategies(base.BaseInfraOptimScenarioTest):
"""Tests with real data for strategies"""
# Minimal version required for list data models
min_microversion = "1.3"
# Minimal version required for _create_one_instance_per_host
compute_min_microversion = base.NOVA_API_VERSION_CREATE_WITH_HOST

View File

@@ -29,6 +29,8 @@ CONF = config.CONF
class TestExecuteVmWorkloadBalanceStrategy(base.BaseInfraOptimScenarioTest):
"""Tests for action plans"""
# Minimal version required for list data models
min_microversion = "1.3"
# Minimal version required for _create_one_instance_per_host
compute_min_microversion = base.NOVA_API_VERSION_CREATE_WITH_HOST

View File

@@ -27,6 +27,8 @@ LOG = log.getLogger(__name__)
class TestExecuteWorkloadBalanceStrategy(base.BaseInfraOptimScenarioTest):
"""Tests for workload_balance"""
# Minimal version required for list data models
min_microversion = "1.3"
# Minimal version required for _create_one_instance_per_host
compute_min_microversion = base.NOVA_API_VERSION_CREATE_WITH_HOST

View File

@@ -31,6 +31,8 @@ LOG = log.getLogger(__name__)
class TestExecuteWorkloadBalancingStrategy(base.BaseInfraOptimScenarioTest):
"""Tests for action plans"""
# Minimal version required for list data models
min_microversion = "1.3"
# Minimal version required for _create_one_instance_per_host
compute_min_microversion = base.NOVA_API_VERSION_CREATE_WITH_HOST

View File

@@ -24,6 +24,8 @@ LOG = log.getLogger(__name__)
class TestExecuteZoneMigrationStrategy(base.BaseInfraOptimScenarioTest):
"""Tests for action plans"""
# Minimal version required for list data models
min_microversion = "1.3"
# Minimal version required for _create_one_instance_per_host
compute_min_microversion = base.NOVA_API_VERSION_CREATE_WITH_HOST