Add tests for and fix RPM version sorting#4146
Conversation
045185b to
05adc6a
Compare
ff88096 to
0d8881a
Compare
|
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. |
85dcb86 to
4e1ff56
Compare
3e8c3f9 to
dc4d08e
Compare
| 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): |
There was a problem hiding this comment.
Test failed successfully https://github.com/pulp/pulp_rpm/actions/runs/17947265654/job/51036889972?pr=4146#step:14:3451
|
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. |
|
|
||
|
|
||
| # internal use: each individual component of the EVR is compared using this function | ||
| def compare_version_strings(first, second): |
There was a problem hiding this comment.
You could make it more obvious that it's only for internal use:
| def compare_version_strings(first, second): | |
| def _compare_version_strings(first, second): |
e713f81 to
ff1f960
Compare
ff1f960 to
0522756
Compare
| 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. |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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("~:") == ("~", "", "") |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
From the fedora docs I thought the tilde could only be used in the version part.
Wild.
There was a problem hiding this comment.
Nothing strictly speaking prevents it. It's a very bad idea though
| """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 |
| # both have caret, strip and continue | ||
| version1_part = version1_stripped | ||
| version2_part = version2_stripped | ||
| continue |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
If it really should not reach here why return 0?
Wdyt of raising an error?
There was a problem hiding this comment.
The skipped ones will be fixed in this other PR, right?
|
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. |
|
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. |
0522756 to
e336ee5
Compare
pedro-psb
left a comment
There was a problem hiding this comment.
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.
No description provided.