Skip to content

Add tests for and fix RPM version sorting#4146

Merged
dralley merged 3 commits into
pulp:mainfrom
dralley:rpmver-tests
Sep 24, 2025
Merged

Add tests for and fix RPM version sorting#4146
dralley merged 3 commits into
pulp:mainfrom
dralley:rpmver-tests

Conversation

@dralley
Copy link
Copy Markdown
Contributor

@dralley dralley commented Sep 22, 2025

No description provided.

@github-actions github-actions Bot added the multi-commit Added when a PR consists of more than one commit label Sep 22, 2025
@dralley dralley force-pushed the rpmver-tests branch 2 times, most recently from ff88096 to 0d8881a Compare September 23, 2025 02:09
@dralley dralley marked this pull request as ready for review September 23, 2025 04:08
@dralley
Copy link
Copy Markdown
Contributor Author

dralley commented Sep 23, 2025

As it turns out, the Python version was not in fact as correct or complete as I was thinking it was. So, this is an overhaul on the algorithm to pass the test suite as ported from my Rust implementation.

This exercise and refresher on the complexities of the algorithm make me heavily suspect that a correct SQL-based implementation is going to be near impossible.

@dralley dralley force-pushed the rpmver-tests branch 8 times, most recently from 85dcb86 to 4e1ff56 Compare September 23, 2025 05:30
@dralley dralley force-pushed the rpmver-tests branch 2 times, most recently from 3e8c3f9 to dc4d08e Compare September 23, 2025 13:20
Comment thread pulp_rpm/tests/unit/test_package_age.py Outdated
self.assertEqual(sorted(epochpkg_ages), [1, 2])

@skip("The implementation of package age is broken w/r/t '^' and '~' characters")
def test_age_with_complex_versions(self):
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dralley dralley changed the title Add tests for RPM version sorting Fix and add tests for RPM version sorting Sep 23, 2025
@dralley
Copy link
Copy Markdown
Contributor Author

dralley commented Sep 23, 2025

I intend this to backport this to all the supported branches. But I have to do it manually because there's multiple commits and I'd rather not squash them.

@dralley dralley changed the title Fix and add tests for RPM version sorting Add tests for and fix RPM version sorting Sep 23, 2025
Comment thread pulp_rpm/app/rpm_version.py Outdated


# internal use: each individual component of the EVR is compared using this function
def compare_version_strings(first, second):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could make it more obvious that it's only for internal use:

Suggested change
def compare_version_strings(first, second):
def _compare_version_strings(first, second):

@dralley dralley force-pushed the rpmver-tests branch 2 times, most recently from e713f81 to ff1f960 Compare September 23, 2025 17:05
Comment thread pulp_rpm/tests/unit/test_rpm_version.py Outdated
Unit tests for RPM version comparison functionality.

These tests are designed to match the behavior tested in the Rust implementation
to ensure compatibility between different RPM version comparison implementations.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a link to the Rust implementation you are refering to?
I know its yours, but someone / sometime later that may not be clear.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll just remove the comment and maybe add a direct link

assert from_evr(":0-") == ("", "0", "")
assert from_evr("0:") == ("0", "", "")
assert from_evr("asdf:") == ("asdf", "", "")
assert from_evr("~:") == ("~", "", "")
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A bit of a tangent for the purpose of this PR (and without thinking much on the consequences), I would argue that most of these are obviously invalid and should raise errors.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For what it's worth this is only exercised during tests so precisely how it behaves doesn't matter much. Strictly speaking we can entirely delete these tests and the from_evr function, it's just helpful to use in the tests

# compare versions with tilde parsing as older
evr1 = RpmVersion.from_string("~3:12.2.3-45")
evr2 = RpmVersion.from_string("0:1.2.3-45")
assert evr1 < evr2
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From the fedora docs I thought the tilde could only be used in the version part.
Wild.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing strictly speaking prevents it. It's a very bad idea though

Comment thread pulp_rpm/tests/unit/test_rpm_version.py Outdated
"""Test some version comparison behavior that is a bit non-intuitive."""
# (but needs to be maintained for compatibility)
assert compare_version_strings("1e.fc33", "1.fc33") < 0
assert compare_version_strings("1g.fc33", "1.fc33") > 0
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤯

# both have caret, strip and continue
version1_part = version1_stripped
version2_part = version2_stripped
continue
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since you are commenting # first < second here, I'd suggest to extract the numbers -1,0,1 to constants such as "FIRST_GREATER", etc, or anything like that.

And can you remove comments 206, 212 and 218? The condition is pretty self explanatory.


def vercmp(first, second):
return Vercmp.compare(first, second)
# Should not reach here due to the checks above, but just in case
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it really should not reach here why return 0?
Wdyt of raising an error?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The skipped ones will be fixed in this other PR, right?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes

@pedro-psb
Copy link
Copy Markdown
Member

Not saying we should do that here, but it ocurred to me:

If we have reference implementations of this (e.g, rpmdev-vercmp and/or your rust one), we could just feed both with a set of inputs and assert this implementation output matches the reference one. The advantage is the we don't have to duplicate the source of truth for the specification correctness here.

@dralley
Copy link
Copy Markdown
Contributor Author

dralley commented Sep 24, 2025

The test suite is essentially copied over from my Rust implementation (literally the same test strings), which in turn is more or less adapted (not exactly copied but it's hitting the same cases) from the upstream tests in rpm. So that's more or less already the case.

I agree with you that it would be nice to get rid of this implementation entirely though.

Copy link
Copy Markdown
Member

@pedro-psb pedro-psb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the clarifications.
Guess you said it better, it would be better to not even have the implementation duplicated here. But if we have to, we are in good shape here.

@dralley dralley merged commit 5e6f3e8 into pulp:main Sep 24, 2025
25 of 27 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

multi-commit Added when a PR consists of more than one commit no-changelog no-issue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants