Skip to content

Commit

Permalink
Implement latest_by_nvr
Browse files Browse the repository at this point in the history
This method has been stubbed out for some time awaiting implementation.
This patch does so, using the toolchest.rpm.rpmvercmp[1] function for
comparing versions of the NVR.

[1]: https://toolchest.readthedocs.io/en/0.0.13/_modules/toolchest/rpm/rpmvercmp.html#rpmvercmp

Signed-off-by: Jason Guiditta <[email protected]>
  • Loading branch information
jguiditta committed Sep 13, 2024
1 parent c9bd077 commit 8a423a5
Show file tree
Hide file tree
Showing 5 changed files with 211 additions and 3 deletions.
20 changes: 18 additions & 2 deletions koji_wrapper/tag.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-

""" KojiTag Module """
from toolchest.rpm.rpmvercmp import rpmvercmp

from koji_wrapper.wrapper import KojiWrapper
from koji_wrapper.validators import validate_required, validate_str_or_list
Expand Down Expand Up @@ -89,8 +90,23 @@ def _filter_tagged(self, tagged_builds):
return self.tagged_list

def latest_by_nvr(self):
# TODO: implement/port _find_latest logic
pass
"""
Return the build from the cached builds list (listTagged) that has the
greatest NVR. This uses the toolchest library to also account for
timestamps and other things that make the koji '--latest' flag not
always return the desired result.
"""
greatest_nvr = None
for build in self.builds():
if greatest_nvr:
# Compare previously found greatest nvr with the next item in
# the list and only change greatest_nvr if the new item is
# greater.
if rpmvercmp(build['nvr'], greatest_nvr['nvr']) == 1:
greatest_nvr = build
else:
greatest_nvr = build
return greatest_nvr

def builds_by_attribute(self, attribute):
"""
Expand Down
Empty file.
170 changes: 170 additions & 0 deletions koji_wrapper/test_support/sample_data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
package_builds_by_tag = [
{
"build_id": 3275129,
"completion_time": "2024-09-09 03:25:39.568158",
"create_event": 60169004,
"creation_event_id": 60168954,
"creation_time": "2024-09-09 03:16:56.806868",
"draft": False,
"epoch": None,
"id": 3275129,
"name": "important-container",
"nvr": "important-container-18.0.0-26.1725851546",
"owner_id": 4119,
"owner_name": "builderbot1",
"package_id": 84908,
"package_name": "important-container",
"promoter_id": None,
"promoter_name": None,
"promotion_time": None,
"release": "26.1725851546",
"start_time": "2024-09-09 03:16:56.802744",
"state": 1,
"tag_id": 139665,
"tag_name": "some_release",
"task_id": 64054213,
"version": "18.0.0",
"volume_id": 0,
"volume_name": "DEFAULT"
},
{
"build_id": 3266643,
"completion_time": "2024-09-04 08:34:18.374651",
"create_event": 60067873,
"creation_event_id": 60067708,
"creation_time": "2024-09-04 08:27:48.275598",
"draft": False,
"epoch": None,
"id": 3266643,
"name": "important-container",
"nvr": "important-container-18.0.0-29",
"owner_id": 6716,
"owner_name": "builderbot2",
"package_id": 84908,
"package_name": "important-container",
"promoter_id": None,
"promoter_name": None,
"promotion_time": None,
"release": "29",
"start_time": "2024-09-04 08:27:48.270981",
"state": 1,
"tag_id": 139665,
"tag_name": "some_release",
"task_id": 63935082,
"version": "18.0.0",
"volume_id": 0,
"volume_name": "DEFAULT"
},
{
"build_id": 3264161,
"completion_time": "2024-09-03 18:35:07.165203",
"create_event": 60055330,
"creation_event_id": 60055144,
"creation_time": "2024-09-03 18:21:12.624179",
"draft": False,
"epoch": None,
"id": 3264161,
"name": "important-container",
"nvr": "important-container-18.0.0-26.1725387536",
"owner_id": 4119,
"owner_name": "builderbot1",
"package_id": 84908,
"package_name": "important-container",
"promoter_id": None,
"promoter_name": None,
"promotion_time": None,
"release": "26.1725387536",
"start_time": "2024-09-03 18:21:12.616153",
"state": 1,
"tag_id": 139665,
"tag_name": "some_release",
"task_id": 63908214,
"version": "18.0.0",
"volume_id": 0,
"volume_name": "DEFAULT"
},
{
"build_id": 3262636,
"completion_time": "2024-09-03 06:52:41.849530",
"create_event": 60042926,
"creation_event_id": 60042686,
"creation_time": "2024-09-03 06:43:17.553500",
"draft": False,
"epoch": None,
"id": 3262636,
"name": "important-container",
"nvr": "important-container-18.0.0-26.1725345668",
"owner_id": 4119,
"owner_name": "builderbot1",
"package_id": 84908,
"package_name": "important-container",
"promoter_id": None,
"promoter_name": None,
"promotion_time": None,
"release": "26.1725345668",
"start_time": "2024-09-03 06:43:17.529565",
"state": 1,
"tag_id": 139665,
"tag_name": "some_release",
"task_id": 63878460,
"version": "18.0.0",
"volume_id": 0,
"volume_name": "DEFAULT"
},
{
"build_id": 3253101,
"completion_time": "2024-08-28 05:39:45.143113",
"create_event": 59926605,
"creation_event_id": 59926588,
"creation_time": "2024-08-28 05:33:36.432830",
"draft": False,
"epoch": None,
"id": 3253101,
"name": "important-container",
"nvr": "important-container-18.0.0-28",
"owner_id": 6716,
"owner_name": "builderbot2",
"package_id": 84908,
"package_name": "important-container",
"promoter_id": None,
"promoter_name": None,
"promotion_time": None,
"release": "28",
"start_time": "2024-08-28 05:33:36.423307",
"state": 1,
"tag_id": 139665,
"tag_name": "some_release",
"task_id": 63734338,
"version": "18.0.0",
"volume_id": 0,
"volume_name": "DEFAULT"
},
{
"build_id": 3242053,
"completion_time": "2024-08-22 04:58:34.746643",
"create_event": 59810140,
"creation_event_id": 59810034,
"creation_time": "2024-08-22 04:47:36.487052",
"draft": False,
"epoch": None,
"id": 3242053,
"name": "important-container",
"nvr": "important-container-18.0.0-27",
"owner_id": 6716,
"owner_name": "builderbot2",
"package_id": 84908,
"package_name": "important-container",
"promoter_id": None,
"promoter_name": None,
"promotion_time": None,
"release": "27",
"start_time": "2024-08-22 04:47:36.482356",
"state": 1,
"tag_id": 139665,
"tag_name": "some_release",
"task_id": 63579965,
"version": "18.0.0",
"volume_id": 0,
"volume_name": "DEFAULT"
}
]
7 changes: 7 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

import pytest

import koji_wrapper.test_support.sample_data as test_data


@pytest.fixture()
def builds_for_tag():
yield test_data.package_builds_by_tag


@pytest.fixture()
def sample_build():
Expand Down
17 changes: 16 additions & 1 deletion tests/unit/test_koji_tag.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ def test_passes_builds_extra_args(sample_tagged_builds):
kt = build_tag('foo')
kt.session.listTagged = MagicMock(return_value=sample_tagged_builds)
assert kt.builds(inherit=True) == sample_tagged_builds
kt.session.listTagged.assert_called()
kt.session.listTagged.assert_called_with('foo', inherit=True)


def test_caches_builds(sample_tagged_builds):
Expand Down Expand Up @@ -145,6 +145,21 @@ def test_filters_builds_by_both(sample_tagged_builds):
assert len(filtered) == 0


def test_selects_latest_build_by_nvr(builds_for_tag):
"""
GIVEN we have a KojiTag object filtered by tag and package
WHEN we call latest_by_nvr
THEN we get the build object with the latest nvr
"""
kt = build_tag('some_release')
kt.session.listTagged = MagicMock(return_value=builds_for_tag)
# In real usage, this is how we would narrow down the build list for the
# tested use case
assert kt.builds(package='important-container') == builds_for_tag
latest = kt.latest_by_nvr()
assert latest['nvr'] == 'important-container-18.0.0-29'


def test_gets_attribute_for_builds_in_list(sample_tagged_builds):
"""
GIVEN we have a KojiTag object
Expand Down

0 comments on commit 8a423a5

Please sign in to comment.