From: Zbigniew Jędrzejewski-Szmek Date: Tue, 17 May 2022 12:33:08 +0000 (+0200) Subject: test-string-util: include a copy of rpm's version comparison tests X-Git-Tag: v252-rc1~939^2~6 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d970092fa5eb41ae095408b3692f1bb997802869;p=thirdparty%2Fsystemd.git test-string-util: include a copy of rpm's version comparison tests We said that strverscmp_improved() is similar to rpm, so it's nice to include their tests too so we can pin down the differences. Our test is changed to print olderolder. (I know the computer doesn't care, but I find it much harder to think about when newer is on the left…) The rpm test strings are copied from https://github.com/rpm-software-management/rpm/blob/master/tests/rpmvercmp.at. rpmio is licensed GPL OR LGPL, so we can do that without any issue. (I think it could be argued as "fair use" anyway, but that's not necessary in this case.) I kept the original form as much as possible so it'll be easy to copy things back and forth in the future. --- diff --git a/src/test/test-string-util.c b/src/test/test-string-util.c index 00163d501ec..d0a4eca3906 100644 --- a/src/test/test-string-util.c +++ b/src/test/test-string-util.c @@ -828,13 +828,24 @@ TEST(string_contains_word) { assert_se(!string_contains_word("a:b:cc", ":#", ":cc")); } -static void test_strverscmp_improved_one(const char *newer, const char *older) { - log_info("/* %s(%s, %s) */", __func__, strnull(newer), strnull(older)); +static void test_strverscmp_improved_one(const char* a, const char *b, int expected) { + int r = strverscmp_improved(a, b); + + log_info("'%s' %s '%s'%s", + strnull(a), + r > 0 ? ">" : r < 0 ? "<" : "==", + strnull(b), + r == expected ? "" : " !!!!!!!!!!!!!"); + assert_se(r == expected); +} + +static void test_strverscmp_improved_newer(const char *older, const char *newer) { + test_strverscmp_improved_one(older, newer, -1); - assert_se(strverscmp_improved(newer, newer) == 0); - assert_se(strverscmp_improved(newer, older) > 0); - assert_se(strverscmp_improved(older, newer) < 0); assert_se(strverscmp_improved(older, older) == 0); + assert_se(strverscmp_improved(older, newer) < 0); + assert_se(strverscmp_improved(newer, older) > 0); + assert_se(strverscmp_improved(newer, newer) == 0); } TEST(strverscmp_improved) { @@ -868,43 +879,189 @@ TEST(strverscmp_improved) { STRV_FOREACH(p, versions) STRV_FOREACH(q, p + 1) - test_strverscmp_improved_one(*q, *p); - - test_strverscmp_improved_one("123.45-67.89", "123.45-67.88"); - test_strverscmp_improved_one("123.45-67.89a", "123.45-67.89"); - test_strverscmp_improved_one("123.45-67.89", "123.45-67.ab"); - test_strverscmp_improved_one("123.45-67.89", "123.45-67.9"); - test_strverscmp_improved_one("123.45-67.89", "123.45-67"); - test_strverscmp_improved_one("123.45-67.89", "123.45-66.89"); - test_strverscmp_improved_one("123.45-67.89", "123.45-9.99"); - test_strverscmp_improved_one("123.45-67.89", "123.42-99.99"); - test_strverscmp_improved_one("123.45-67.89", "123-99.99"); + test_strverscmp_improved_newer(*p, *q); + + test_strverscmp_improved_newer("123.45-67.88", "123.45-67.89"); + test_strverscmp_improved_newer("123.45-67.89", "123.45-67.89a"); + test_strverscmp_improved_newer("123.45-67.ab", "123.45-67.89"); + test_strverscmp_improved_newer("123.45-67.9", "123.45-67.89"); + test_strverscmp_improved_newer("123.45-67", "123.45-67.89"); + test_strverscmp_improved_newer("123.45-66.89", "123.45-67.89"); + test_strverscmp_improved_newer("123.45-9.99", "123.45-67.89"); + test_strverscmp_improved_newer("123.42-99.99", "123.45-67.89"); + test_strverscmp_improved_newer("123-99.99", "123.45-67.89"); /* '~' : pre-releases */ - test_strverscmp_improved_one("123.45-67.89", "123~rc1-99.99"); - test_strverscmp_improved_one("123-45.67.89", "123~rc1-99.99"); - test_strverscmp_improved_one("123~rc2-67.89", "123~rc1-99.99"); - test_strverscmp_improved_one("123^aa2-67.89", "123~rc1-99.99"); - test_strverscmp_improved_one("123aa2-67.89", "123~rc1-99.99"); + test_strverscmp_improved_newer("123~rc1-99.99", "123.45-67.89"); + test_strverscmp_improved_newer("123~rc1-99.99", "123-45.67.89"); + test_strverscmp_improved_newer("123~rc1-99.99", "123~rc2-67.89"); + test_strverscmp_improved_newer("123~rc1-99.99", "123^aa2-67.89"); + test_strverscmp_improved_newer("123~rc1-99.99", "123aa2-67.89"); /* '-' : separator between version and release. */ - test_strverscmp_improved_one("123.45-67.89", "123-99.99"); - test_strverscmp_improved_one("123^aa2-67.89", "123-99.99"); - test_strverscmp_improved_one("123aa2-67.89", "123-99.99"); + test_strverscmp_improved_newer("123-99.99", "123.45-67.89"); + test_strverscmp_improved_newer("123-99.99", "123^aa2-67.89"); + test_strverscmp_improved_newer("123-99.99", "123aa2-67.89"); /* '^' : patch releases */ - test_strverscmp_improved_one("123.45-67.89", "123^45-67.89"); - test_strverscmp_improved_one("123^aa2-67.89", "123^aa1-99.99"); - test_strverscmp_improved_one("123aa2-67.89", "123^aa2-67.89"); + test_strverscmp_improved_newer("123^45-67.89", "123.45-67.89"); + test_strverscmp_improved_newer("123^aa1-99.99", "123^aa2-67.89"); + test_strverscmp_improved_newer("123^aa2-67.89", "123aa2-67.89"); /* '.' : point release */ - test_strverscmp_improved_one("123aa2-67.89", "123.aa2-67.89"); - test_strverscmp_improved_one("123.ab2-67.89", "123.aa2-67.89"); + test_strverscmp_improved_newer("123.aa2-67.89", "123aa2-67.89"); + test_strverscmp_improved_newer("123.aa2-67.89", "123.ab2-67.89"); /* invalid characters */ assert_se(strverscmp_improved("123_aa2-67.89", "123aa+2-67.89") == 0); } +#define RPMVERCMP(a, b, c) \ + test_strverscmp_improved_one(STRINGIFY(a), STRINGIFY(b), (c)) + +TEST(strverscmp_improved_rpm) { + /* Tests copied from rmp's rpmio test suite, under the LGPL license: + * https://github.com/rpm-software-management/rpm/blob/master/tests/rpmvercmp.at. + * The original form is retained for easy comparisons and updates. + */ + + RPMVERCMP(1.0, 1.0, 0); + RPMVERCMP(1.0, 2.0, -1); + RPMVERCMP(2.0, 1.0, 1); + + RPMVERCMP(2.0.1, 2.0.1, 0); + RPMVERCMP(2.0, 2.0.1, -1); + RPMVERCMP(2.0.1, 2.0, 1); + + RPMVERCMP(2.0.1a, 2.0.1a, 0); + RPMVERCMP(2.0.1a, 2.0.1, 1); + RPMVERCMP(2.0.1, 2.0.1a, -1); + + RPMVERCMP(5.5p1, 5.5p1, 0); + RPMVERCMP(5.5p1, 5.5p2, -1); + RPMVERCMP(5.5p2, 5.5p1, 1); + + RPMVERCMP(5.5p10, 5.5p10, 0); + RPMVERCMP(5.5p1, 5.5p10, -1); + RPMVERCMP(5.5p10, 5.5p1, 1); + + RPMVERCMP(10xyz, 10.1xyz, 1); /* Note: this is reversed from rpm's vercmp */ + RPMVERCMP(10.1xyz, 10xyz, -1); /* Note: this is reversed from rpm's vercmp */ + + RPMVERCMP(xyz10, xyz10, 0); + RPMVERCMP(xyz10, xyz10.1, -1); + RPMVERCMP(xyz10.1, xyz10, 1); + + RPMVERCMP(xyz.4, xyz.4, 0); + RPMVERCMP(xyz.4, 8, -1); + RPMVERCMP(8, xyz.4, 1); + RPMVERCMP(xyz.4, 2, -1); + RPMVERCMP(2, xyz.4, 1); + + RPMVERCMP(5.5p2, 5.6p1, -1); + RPMVERCMP(5.6p1, 5.5p2, 1); + + RPMVERCMP(5.6p1, 6.5p1, -1); + RPMVERCMP(6.5p1, 5.6p1, 1); + + RPMVERCMP(6.0.rc1, 6.0, 1); + RPMVERCMP(6.0, 6.0.rc1, -1); + + RPMVERCMP(10b2, 10a1, 1); + RPMVERCMP(10a2, 10b2, -1); + + RPMVERCMP(1.0aa, 1.0aa, 0); + RPMVERCMP(1.0a, 1.0aa, -1); + RPMVERCMP(1.0aa, 1.0a, 1); + + RPMVERCMP(10.0001, 10.0001, 0); + RPMVERCMP(10.0001, 10.1, 0); + RPMVERCMP(10.1, 10.0001, 0); + RPMVERCMP(10.0001, 10.0039, -1); + RPMVERCMP(10.0039, 10.0001, 1); + + RPMVERCMP(4.999.9, 5.0, -1); + RPMVERCMP(5.0, 4.999.9, 1); + + RPMVERCMP(20101121, 20101121, 0); + RPMVERCMP(20101121, 20101122, -1); + RPMVERCMP(20101122, 20101121, 1); + + RPMVERCMP(2_0, 2_0, 0); + RPMVERCMP(2.0, 2_0, -1); /* Note: in rpm those compare equal */ + RPMVERCMP(2_0, 2.0, 1); /* Note: in rpm those compare equal */ + + /* RhBug:178798 case */ + RPMVERCMP(a, a, 0); + RPMVERCMP(a+, a+, 0); + RPMVERCMP(a+, a_, 0); + RPMVERCMP(a_, a+, 0); + RPMVERCMP(+a, +a, 0); + RPMVERCMP(+a, _a, 0); + RPMVERCMP(_a, +a, 0); + RPMVERCMP(+_, +_, 0); + RPMVERCMP(_+, +_, 0); + RPMVERCMP(_+, _+, 0); + RPMVERCMP(+, _, 0); + RPMVERCMP(_, +, 0); + + /* Basic testcases for tilde sorting */ + RPMVERCMP(1.0~rc1, 1.0~rc1, 0); + RPMVERCMP(1.0~rc1, 1.0, -1); + RPMVERCMP(1.0, 1.0~rc1, 1); + RPMVERCMP(1.0~rc1, 1.0~rc2, -1); + RPMVERCMP(1.0~rc2, 1.0~rc1, 1); + RPMVERCMP(1.0~rc1~git123, 1.0~rc1~git123, 0); + RPMVERCMP(1.0~rc1~git123, 1.0~rc1, -1); + RPMVERCMP(1.0~rc1, 1.0~rc1~git123, 1); + + /* Basic testcases for caret sorting */ + RPMVERCMP(1.0^, 1.0^, 0); + RPMVERCMP(1.0^, 1.0, 1); + RPMVERCMP(1.0, 1.0^, -1); + RPMVERCMP(1.0^git1, 1.0^git1, 0); + RPMVERCMP(1.0^git1, 1.0, 1); + RPMVERCMP(1.0, 1.0^git1, -1); + RPMVERCMP(1.0^git1, 1.0^git2, -1); + RPMVERCMP(1.0^git2, 1.0^git1, 1); + RPMVERCMP(1.0^git1, 1.01, -1); + RPMVERCMP(1.01, 1.0^git1, 1); + RPMVERCMP(1.0^20160101, 1.0^20160101, 0); + RPMVERCMP(1.0^20160101, 1.0.1, -1); + RPMVERCMP(1.0.1, 1.0^20160101, 1); + RPMVERCMP(1.0^20160101^git1, 1.0^20160101^git1, 0); + RPMVERCMP(1.0^20160102, 1.0^20160101^git1, 1); + RPMVERCMP(1.0^20160101^git1, 1.0^20160102, -1); + + /* Basic testcases for tilde and caret sorting */ + RPMVERCMP(1.0~rc1^git1, 1.0~rc1^git1, 0); + RPMVERCMP(1.0~rc1^git1, 1.0~rc1, 1); + RPMVERCMP(1.0~rc1, 1.0~rc1^git1, -1); + RPMVERCMP(1.0^git1~pre, 1.0^git1~pre, 0); + RPMVERCMP(1.0^git1, 1.0^git1~pre, 1); + RPMVERCMP(1.0^git1~pre, 1.0^git1, -1); + + /* These are included here to document current, arguably buggy behaviors + * for reference purposes and for easy checking against unintended + * behavior changes. */ + log_info("/* RPM version comparison oddities */"); + /* RhBug:811992 case */ + RPMVERCMP(1b.fc17, 1b.fc17, 0); + RPMVERCMP(1b.fc17, 1.fc17, 1); /* Note: this is reversed from rpm's vercmp, WAT! */ + RPMVERCMP(1.fc17, 1b.fc17, -1); + RPMVERCMP(1g.fc17, 1g.fc17, 0); + RPMVERCMP(1g.fc17, 1.fc17, 1); + RPMVERCMP(1.fc17, 1g.fc17, -1); + + /* Non-ascii characters are considered equal so these are all the same, eh… */ + RPMVERCMP(1.1.α, 1.1.α, 0); + RPMVERCMP(1.1.α, 1.1.β, 0); + RPMVERCMP(1.1.β, 1.1.α, 0); + RPMVERCMP(1.1.αα, 1.1.α, 0); + RPMVERCMP(1.1.α, 1.1.ββ, 0); + RPMVERCMP(1.1.ββ, 1.1.αα, 0); +} + TEST(strextendf) { _cleanup_free_ char *p = NULL;