1
0
forked from rpms/leapp

Bump leapp-framework version

Bump the package release
This commit is contained in:
Yuriy Kohut 2026-06-30 20:52:54 +03:00
parent e34e206747
commit 7083418c02
3 changed files with 265 additions and 2 deletions

View File

@ -0,0 +1,228 @@
From 66883ef34b1e241838b9812a8920bf6f6fb380e0 Mon Sep 17 00:00:00 2001
From: Matej Matuska <mmatuska@redhat.com>
Date: Wed, 20 May 2026 12:32:48 +0200
Subject: [PATCH] Fix exception in normalize_schemas for conflicting actor
config schemas
The normalize_schemas function incorrectly raises an exception when a
config schema (subclass of Config) is contained more than once in it's
input, regardless of whether it's a conflicting (same section and name,
but a difference in other members) or the same (same section and name).
Traceback:
Traceback (most recent call last):
File "/usr/bin/leapp", line 33, in <module>
sys.exit(load_entry_point('leapp==0.21.0', 'console_scripts', 'leapp')())
File "/usr/lib/python3.9/site-packages/leapp/cli/__init__.py", line 51, in main
cli.command.execute('leapp version {}'.format(VERSION))
File "/usr/lib/python3.9/site-packages/leapp/utils/clicmd.py", line 111, in execute
args.func(args)
File "/usr/lib/python3.9/site-packages/leapp/utils/clicmd.py", line 133, in called
self.target(args)
File "/usr/lib/python3.9/site-packages/leapp/cli/commands/upgrade/breadcrumbs.py", line 169, in wrapper
return f(*args, breadcrumbs=breadcrumbs, **kwargs)
File "/usr/lib/python3.9/site-packages/leapp/cli/commands/preupgrade/__init__.py", line 86, in preupgrade
command_utils.load_actor_configs_and_store_it_in_db(context, repositories, cfg)
File "/usr/lib/python3.9/site-packages/leapp/cli/commands/command_utils.py", line 291, in load_actor_configs_and_store_it_in_db
actor_config_schemas = actor_config.normalize_schemas(actor_config_schemas)
File "/usr/lib/python3.9/site-packages/leapp/actors/config.py", line 180, in normalize_schemas
if unique_name in added_fields and added_fields[unique_name] != field:
TypeError: 'set' object is not subscriptable
The added_fields variable is a set. The condition for checking conflicts
attempts to do indexing on the set, which is not possible in Python sets
and results in a TypeError.
This patch removes the set altogether since it doesn't bring any
advantage over just using the normalized_schemas dict.
Also add unit tests for the function.
---
leapp/actors/config.py | 44 ++++++-----
tests/scripts/test_actor_config.py | 114 +++++++++++++++++++++++++++++
2 files changed, 138 insertions(+), 20 deletions(-)
create mode 100644 tests/scripts/test_actor_config.py
diff --git a/leapp/actors/config.py b/leapp/actors/config.py
index 55775d5..d952bb6 100644
--- a/leapp/actors/config.py
+++ b/leapp/actors/config.py
@@ -169,31 +169,35 @@ def _get_config(config_dir='/etc/leapp/actor_conf.d'):
def normalize_schemas(schemas):
"""
Merge all schemas into a single dictionary and validate them for errors we can detect.
+
+ :param schemas: List of schemas to normalize
+ :type schemas: Iterable[Iterable[Type[Config]]]
+ :return A dictionary with structure: section -> name -> Config
+ :rtype: DefaultDict[str, Dict[str, Type[Config]]]
"""
- added_fields = set()
normalized_schema = defaultdict(dict)
for schema in schemas:
for field in schema:
- unique_name = (field.section, field.name)
-
+ # section and name are the unique key for a config
+ existing_field = normalized_schema[field.section].get(field.name, None)
# Error if the field has been added by another schema
- if unique_name in added_fields and added_fields[unique_name] != field:
- # TODO: Also include information on what Actor contains the
- # conflicting fields but that information isn't passed into
- # this function right now.
- message = ('Two actors added incompatible configuration items'
- ' with the same name for Section: {section},'
- ' Field: {field}'.format(section=field.section,
- field=field.name))
- log.error(message)
- raise SchemaError(message)
-
- # TODO: More validation here.
-
- # Store the fields from the schema in a way that we can easily look
- # up while validating
- added_fields.add(unique_name)
- normalized_schema[field.section][field.name] = field
+ if existing_field:
+ if existing_field != field:
+ # TODO: Also include information on what Actor contains the
+ # conflicting fields but that information isn't passed into
+ # this function right now.
+ message = (
+ 'Two actors added incompatible configuration items with'
+ ' the same name for Section: {section}, Field: {field}'
+ ).format(section=field.section, field=field.name)
+
+ log.error(message)
+ raise SchemaError(message)
+
+ # TODO: More validation here.
+
+ else:
+ normalized_schema[field.section][field.name] = field
return normalized_schema
diff --git a/tests/scripts/test_actor_config.py b/tests/scripts/test_actor_config.py
new file mode 100644
index 0000000..b8c02cd
--- /dev/null
+++ b/tests/scripts/test_actor_config.py
@@ -0,0 +1,114 @@
+from collections import defaultdict
+import pytest
+
+from leapp.actors.config import Config, SchemaError, normalize_schemas
+from leapp.models import fields
+
+
+class _TestConfigA(Config):
+ section = "test"
+ name = "a_setting"
+ type_ = fields.String()
+ description = 'Description here'
+ default = "default value"
+
+
+class _TestConfigB(Config):
+ section = "other_section"
+ name = "other_setting"
+ type_ = fields.String()
+ description = 'Description here'
+ default = "some default value"
+
+
+# conflicts in default
+class _TestConfigConflictsInDefault(Config):
+ section = "test"
+ name = "a_setting"
+ type_ = fields.String()
+ description = 'Description here'
+ default = "different than in A"
+
+
+# conflicts in type_
+class _TestConfigConflictsInType(Config):
+ section = "test"
+ name = "a_setting"
+ type_ = fields.Integer()
+ description = 'Description here'
+ default = "default value"
+
+
+@pytest.mark.parametrize(
+ "schemas",
+ [
+ # test configs from single actors are merged
+ [(_TestConfigA, _TestConfigB)],
+ # test configs from multiple actors are merged
+ [(_TestConfigA,), (_TestConfigB,)],
+ # test "deduplication"
+ [(_TestConfigA, _TestConfigA, _TestConfigB)],
+ [(_TestConfigA,), (_TestConfigA, _TestConfigB,)]
+ ],
+)
+def test_normalize_schemas_ok(schemas):
+ """
+ Test that valid schemas are detected and if required deduplicated
+ """
+ expect = defaultdict(dict)
+ expect["test"] = {"a_setting": _TestConfigA}
+ expect["other_section"] = {"other_setting": _TestConfigB}
+ ret = normalize_schemas(schemas)
+ assert ret == expect
+
+
+def test_normalize_schemas_identical():
+ """
+ Test that identical Config class objects are deduplicated
+ """
+ expect = defaultdict(dict)
+ expect["test"] = {"a_setting": _TestConfigA}
+
+ config = _TestConfigA
+
+ schemas = [(config, config)]
+ ret = normalize_schemas(schemas)
+ assert ret == expect
+
+ schemas = [(config,), (config,)]
+ ret = normalize_schemas(schemas)
+ assert ret == expect
+
+
+@pytest.mark.parametrize(
+ "schemas",
+ [
+ [(_TestConfigA, _TestConfigConflictsInDefault)],
+ [(_TestConfigA, _TestConfigConflictsInType)],
+ ]
+)
+def test_normalize_schemas_intra_conflict(schemas):
+ """
+ Test that conflicts within a single Actor config schema are detected
+ """
+ with pytest.raises(SchemaError):
+ normalize_schemas(schemas)
+
+
+@pytest.mark.parametrize(
+ "schemas",
+ [
+ [(_TestConfigA,), (_TestConfigConflictsInDefault,)],
+ [(_TestConfigA,), (_TestConfigConflictsInType,)],
+ ]
+)
+def test_normalize_schemas_inter_conflict(schemas):
+ """
+ Test that conflicts between multiple Actor config schemas are detected
+ """
+ with pytest.raises(SchemaError):
+ normalize_schemas(schemas)
+
+
+def test_normalize_schemas_empty():
+ assert normalize_schemas([]) == defaultdict(dict)
--
2.54.0

View File

@ -0,0 +1,28 @@
From 0a5b9b7bb44fbe71c97b10673be71e343abcf58c Mon Sep 17 00:00:00 2001
From: Matej Matuska <mmatuska@redhat.com>
Date: Wed, 20 May 2026 12:45:21 +0200
Subject: [PATCH] Makefile: add test_no_lint
The test rules always lints, add a variant which just tests.
---
Makefile | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/Makefile b/Makefile
index a68b8fe..dd2d8b9 100644
--- a/Makefile
+++ b/Makefile
@@ -202,6 +202,10 @@ test: lint
@ $(ENTER_VENV) \
pytest -vv --cov-report term-missing --cov=leapp tests/scripts
+test_no_lint:
+ @ $(ENTER_VENV) \
+ pytest -vv --cov-report term-missing --cov=leapp tests/scripts
+
# TODO(pstodulk): create ticket to add rhel10 for testing.... py: 3.12
test_container:
@case $(_TEST_CONTAINER) in \
--
2.54.0

View File

@ -7,7 +7,7 @@
# it. In case of upstream, dependencies are set differently, but YUM is not
# capable enough to deal with them correctly all the time; we continue to use
# simplified deps in RHEL to ensure that YUM can deal with it.
%global framework_version 6.5
%global framework_version 6.6
# IMPORTANT: everytime the requirements are changed, increment number by one
# - same for Provides in deps subpackage
@ -37,7 +37,7 @@
Name: leapp
Version: 0.21.0
Release: 2%{?dist}
Release: 2%{?dist}.elevate.1
Summary: OS & Application modernization framework
License: ASL 2.0
@ -75,6 +75,8 @@ Patch0007: 0007-reporting-fix-incorrect-converting-of-list-based-com.patch
Patch0008: 0008-fixup-reporting-fix-incorrect-converting-of-list-bas.patch
Patch0009: 0009-python-test-deps-update-pytest-requirements.patch
Patch0010: 0010-fix-reporting-use-single-quoting-when-converting-rem.patch
Patch0011: 0011-Fix-exception-in-normalize_schemas-for-conflicting-a.patch
Patch0012: 0012-Makefile-add-test_no_lint.patch
%description
@ -182,6 +184,8 @@ Requires: findutils
%patch -P 0008 -p1
%patch -P 0009 -p1
%patch -P 0010 -p1
%patch -P 0011 -p1
%patch -P 0012 -p1
##################################################
# Build
##################################################
@ -265,6 +269,9 @@ install -m 0644 -p man/leapp.1 %{buildroot}%{_mandir}/man1/
# no files here
%changelog
* Tue Jun 30 2026 Yuriy Kohut <ykohut@almalinux.org> - 0.21.0-1.elevate.1
- Bump leapp-framework to 6.6
* Fri Apr 17 2026 Matej Matuska <mmatuska@redhat.com> - 0.21.0-1
- Bump leapp-framework to 6.5
- Change how commands are converted for text based report from the list representation