tests: verify `SetConstIterator` works in Python bindings

The problem is that the assignment statement in Python never copies
objects, this means that when we get a reference (returned by
`SetConstIterator::operator*()` to internal query object it is valid
only as long as the query lives.

This means that without additional changes this is a problem for
`RepoQuery`, `GroupQuery` and `EnvironmentQuery`. For me it doesn't
crash with `RepoQuery` (probably due to different memory layout) but it
is caught when run with Sanitizers or valgrind.

To verify with valgrind:
from `dnf5/test/python3/libdnf5` do
`$ PROJECT_BINARY_DIR=../../../build \
PROJECT_SOURCE_DIR=../../../ valgrind python3.13 -m unittest \
repo.test_repo_query.TestRepoQuery.test_repo_query`

This behavior is unexpected in Python, it should manage livetimes
automatically.
This commit is contained in:
Aleš Matěj 2025-07-08 12:09:06 +02:00 committed by pkratoch
parent 2282ae41a5
commit 6ae73f6c5d
2 changed files with 29 additions and 0 deletions

View File

@ -45,3 +45,22 @@ class TestGroup(base_test_case.BaseTestCase):
query = libdnf5.comps.GroupQuery(self.base)
core_group = next(iter(query))
self.assertEqual(5, len(core_group.get_packages()))
def test_group_when_query_out_of_scope(self):
self.add_repo_repomd("repomd-comps-core")
def get_group(base):
query = libdnf5.comps.GroupQuery(base)
return next(iter(query))
self.assertEqual(5, len(get_group(self.base).get_packages()))
def test_iterating_over_inline_query(self):
self.add_repo_repomd("repomd-comps-core", False)
self.add_repo_repomd("repomd-comps-standard")
ids = []
for grp in sorted(libdnf5.comps.GroupQuery(self.base), key=lambda x: int(x.get_order_int())):
ids.append(grp.get_groupid())
self.assertEqual(['core', 'standard'], ids)

View File

@ -70,3 +70,13 @@ class TestRepoQuery(base_test_case.BaseTestCase):
result.add(repo.get_id())
self.assertEqual(
result, {"repo1", "repo2", "repo1_updates", "repo2_updates"})
# Tests repo objects after query goes out of scope
repos_list = []
for repo in libdnf5.repo.RepoQuery(self.base):
repos_list.append(repo)
result = set()
for repo in repos_list:
result.add(repo.get_id())
self.assertEqual(
result, {"repo1", "repo2", "repo1_updates", "repo2_updates"})