|
|
|
@ -15,7 +15,6 @@
|
|
|
|
|
package rpm
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"strings"
|
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
@ -34,31 +33,27 @@ func TestParse(t *testing.T) {
|
|
|
|
|
err bool
|
|
|
|
|
}{
|
|
|
|
|
// Test 0
|
|
|
|
|
{"0", version{epoch: 0, version: "0", revision: ""}, false},
|
|
|
|
|
{"0:0", version{epoch: 0, version: "0", revision: ""}, false},
|
|
|
|
|
{"0:0-", version{epoch: 0, version: "0", revision: ""}, false},
|
|
|
|
|
{"0:0-0", version{epoch: 0, version: "0", revision: "0"}, false},
|
|
|
|
|
{"0:0.0-0.0", version{epoch: 0, version: "0.0", revision: "0.0"}, false},
|
|
|
|
|
{"0", version{epoch: 0, version: "0", release: ""}, false},
|
|
|
|
|
{"0:0", version{epoch: 0, version: "0", release: ""}, false},
|
|
|
|
|
{"0:0-", version{epoch: 0, version: "0", release: ""}, false},
|
|
|
|
|
{"0:0-0", version{epoch: 0, version: "0", release: "0"}, false},
|
|
|
|
|
{"0:0.0-0.0", version{epoch: 0, version: "0.0", release: "0.0"}, false},
|
|
|
|
|
// Test epoched
|
|
|
|
|
{"1:0", version{epoch: 1, version: "0", revision: ""}, false},
|
|
|
|
|
{"5:1", version{epoch: 5, version: "1", revision: ""}, false},
|
|
|
|
|
{"1:0", version{epoch: 1, version: "0", release: ""}, false},
|
|
|
|
|
{"5:1", version{epoch: 5, version: "1", release: ""}, false},
|
|
|
|
|
// Test multiple hypens
|
|
|
|
|
{"0:0-0-0", version{epoch: 0, version: "0-0", revision: "0"}, false},
|
|
|
|
|
{"0:0-0-0-0", version{epoch: 0, version: "0-0-0", revision: "0"}, false},
|
|
|
|
|
{"0:0-0-0", version{epoch: 0, version: "0", release: "0-0"}, false},
|
|
|
|
|
{"0:0-0-0-0", version{epoch: 0, version: "0", release: "0-0-0"}, false},
|
|
|
|
|
// Test multiple colons
|
|
|
|
|
{"0:0:0-0", version{epoch: 0, version: "0:0", revision: "0"}, false},
|
|
|
|
|
{"0:0:0:0-0", version{epoch: 0, version: "0:0:0", revision: "0"}, false},
|
|
|
|
|
{"0:0:0-0", version{epoch: 0, version: "0:0", release: "0"}, false},
|
|
|
|
|
{"0:0:0:0-0", version{epoch: 0, version: "0:0:0", release: "0"}, false},
|
|
|
|
|
// Test multiple hyphens and colons
|
|
|
|
|
{"0:0:0-0-0", version{epoch: 0, version: "0:0-0", revision: "0"}, false},
|
|
|
|
|
{"0:0-0:0-0", version{epoch: 0, version: "0-0:0", revision: "0"}, false},
|
|
|
|
|
// Test valid characters in version
|
|
|
|
|
{"0:09azAZ.-+~:_-0", version{epoch: 0, version: "09azAZ.-+~:_", revision: "0"}, false},
|
|
|
|
|
// Test valid characters in debian revision
|
|
|
|
|
{"0:0-azAZ09.+~_", version{epoch: 0, version: "0", revision: "azAZ09.+~_"}, false},
|
|
|
|
|
{"0:0:0-0-0", version{epoch: 0, version: "0:0", release: "0-0"}, false},
|
|
|
|
|
{"0:0-0:0-0", version{epoch: 0, version: "0", release: "0:0-0"}, false},
|
|
|
|
|
// Test version with leading and trailing spaces
|
|
|
|
|
{" 0:0-1", version{epoch: 0, version: "0", revision: "1"}, false},
|
|
|
|
|
{"0:0-1 ", version{epoch: 0, version: "0", revision: "1"}, false},
|
|
|
|
|
{" 0:0-1 ", version{epoch: 0, version: "0", revision: "1"}, false},
|
|
|
|
|
{" 0:0-1", version{epoch: 0, version: "0", release: "1"}, false},
|
|
|
|
|
{"0:0-1 ", version{epoch: 0, version: "0", release: "1"}, false},
|
|
|
|
|
{" 0:0-1 ", version{epoch: 0, version: "0", release: "1"}, false},
|
|
|
|
|
// Test empty version
|
|
|
|
|
{"", version{}, true},
|
|
|
|
|
{" ", version{}, true},
|
|
|
|
@ -71,7 +66,7 @@ func TestParse(t *testing.T) {
|
|
|
|
|
{"a:0-0", version{}, true},
|
|
|
|
|
{"A:0-0", version{}, true},
|
|
|
|
|
// Test version not starting with a digit
|
|
|
|
|
{"0:abc3-0", version{}, true},
|
|
|
|
|
{"0:abc3-0", version{epoch: 0, version: "abc3", release: "0"}, false},
|
|
|
|
|
}
|
|
|
|
|
for _, c := range cases {
|
|
|
|
|
v, err := newVersion(c.str)
|
|
|
|
@ -83,20 +78,6 @@ func TestParse(t *testing.T) {
|
|
|
|
|
}
|
|
|
|
|
assert.Equal(t, c.ver, v, "When parsing '%s'", c.str)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Test invalid characters in version
|
|
|
|
|
versym := []rune{'!', '#', '@', '$', '%', '&', '/', '|', '\\', '<', '>', '(', ')', '[', ']', '{', '}', ';', ',', '=', '*', '^', '\''}
|
|
|
|
|
for _, r := range versym {
|
|
|
|
|
_, err := newVersion(strings.Join([]string{"0:0", string(r), "-0"}, ""))
|
|
|
|
|
assert.Error(t, err, "Parsing with invalid character '%s' in version should have failed", string(r))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Test invalid characters in revision
|
|
|
|
|
versym = []rune{'!', '#', '@', '$', '%', '&', '/', '|', '\\', '<', '>', '(', ')', '[', ']', '{', '}', ':', ';', ',', '=', '*', '^', '\''}
|
|
|
|
|
for _, r := range versym {
|
|
|
|
|
_, err := newVersion(strings.Join([]string{"0:0-", string(r)}, ""))
|
|
|
|
|
assert.Error(t, err, "Parsing with invalid character '%s' in revision should have failed", string(r))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestParseAndCompare(t *testing.T) {
|
|
|
|
@ -105,79 +86,117 @@ func TestParseAndCompare(t *testing.T) {
|
|
|
|
|
expected int
|
|
|
|
|
v2 string
|
|
|
|
|
}{
|
|
|
|
|
{"7.6p2-4", GREATER, "7.6-0"},
|
|
|
|
|
{"1.0.3-3", GREATER, "1.0-1"},
|
|
|
|
|
{"1.3", GREATER, "1.2.2-2"},
|
|
|
|
|
{"1.3", GREATER, "1.2.2"},
|
|
|
|
|
// Some properties of text strings
|
|
|
|
|
{"0-pre", EQUAL, "0-pre"},
|
|
|
|
|
{"0-pre", LESS, "0-pree"},
|
|
|
|
|
{"1.1.6r2-2", GREATER, "1.1.6r-1"},
|
|
|
|
|
{"2.6b2-1", GREATER, "2.6b-2"},
|
|
|
|
|
{"98.1p5-1", LESS, "98.1-pre2-b6-2"},
|
|
|
|
|
{"0.4a6-2", GREATER, "0.4-1"},
|
|
|
|
|
{"1:3.0.5-2", LESS, "1:3.0.5.1"},
|
|
|
|
|
// epochs
|
|
|
|
|
{"1:0.4", GREATER, "10.3"},
|
|
|
|
|
{"1:1.25-4", LESS, "1:1.25-8"},
|
|
|
|
|
{"0:1.18.36", EQUAL, "1.18.36"},
|
|
|
|
|
{"1.18.36", GREATER, "1.18.35"},
|
|
|
|
|
{"0:1.18.36", GREATER, "1.18.35"},
|
|
|
|
|
// Funky, but allowed, characters in upstream version
|
|
|
|
|
{"9:1.18.36:5.4-20", LESS, "10:0.5.1-22"},
|
|
|
|
|
{"9:1.18.36:5.4-20", LESS, "9:1.18.36:5.5-1"},
|
|
|
|
|
{"9:1.18.36:5.4-20", LESS, " 9:1.18.37:4.3-22"},
|
|
|
|
|
{"1.18.36-0.17.35-18", GREATER, "1.18.36-19"},
|
|
|
|
|
// Junk
|
|
|
|
|
{"1:1.2.13-3", LESS, "1:1.2.13-3.1"},
|
|
|
|
|
{"2.0.7pre1-4", LESS, "2.0.7r-1"},
|
|
|
|
|
// if a version includes a dash, it should be the debrev dash - policy says so
|
|
|
|
|
{"0:0-0-0", GREATER, "0-0"},
|
|
|
|
|
// do we like strange versions? Yes we like strange versions…
|
|
|
|
|
{"0", EQUAL, "0"},
|
|
|
|
|
{"0", EQUAL, "00"},
|
|
|
|
|
// #205960
|
|
|
|
|
{"3.0~rc1-1", LESS, "3.0-1"},
|
|
|
|
|
// #573592 - debian policy 5.6.12
|
|
|
|
|
{"1.0", EQUAL, "1.0-0"},
|
|
|
|
|
{"0.2", LESS, "1.0-0"},
|
|
|
|
|
{"1.0", LESS, "1.0-0+b1"},
|
|
|
|
|
{"1.0", GREATER, "1.0-0~"},
|
|
|
|
|
// "steal" the testcases from (old perl) cupt
|
|
|
|
|
{"1.2.3", EQUAL, "1.2.3"}, // identical
|
|
|
|
|
{"4.4.3-2", EQUAL, "4.4.3-2"}, // identical
|
|
|
|
|
{"1:2ab:5", EQUAL, "1:2ab:5"}, // this is correct...
|
|
|
|
|
{"7:1-a:b-5", EQUAL, "7:1-a:b-5"}, // and this
|
|
|
|
|
{"57:1.2.3abYZ+~-4-5", EQUAL, "57:1.2.3abYZ+~-4-5"}, // and those too
|
|
|
|
|
{"1.2.3", EQUAL, "0:1.2.3"}, // zero epoch
|
|
|
|
|
{"1.2.3", EQUAL, "1.2.3-0"}, // zero revision
|
|
|
|
|
{"009", EQUAL, "9"}, // zeroes…
|
|
|
|
|
{"009ab5", EQUAL, "9ab5"}, // there as well
|
|
|
|
|
{"1.2.3", LESS, "1.2.3-1"}, // added non-zero revision
|
|
|
|
|
{"1.2.3", LESS, "1.2.4"}, // just bigger
|
|
|
|
|
{"1.2.4", GREATER, "1.2.3"}, // order doesn't matter
|
|
|
|
|
{"1.2.24", GREATER, "1.2.3"}, // bigger, eh?
|
|
|
|
|
{"0.10.0", GREATER, "0.8.7"}, // bigger, eh?
|
|
|
|
|
{"3.2", GREATER, "2.3"}, // major number rocks
|
|
|
|
|
{"1.3.2a", GREATER, "1.3.2"}, // letters rock
|
|
|
|
|
{"0.5.0~git", LESS, "0.5.0~git2"}, // numbers rock
|
|
|
|
|
{"2a", LESS, "21"}, // but not in all places
|
|
|
|
|
{"1.3.2a", LESS, "1.3.2b"}, // but there is another letter
|
|
|
|
|
{"1:1.2.3", GREATER, "1.2.4"}, // epoch rocks
|
|
|
|
|
{"1:1.2.3", LESS, "1:1.2.4"}, // bigger anyway
|
|
|
|
|
{"1.2a+~bCd3", LESS, "1.2a++"}, // tilde doesn't rock
|
|
|
|
|
{"1.2a+~bCd3", GREATER, "1.2a+~"}, // but first is longer!
|
|
|
|
|
{"5:2", GREATER, "304-2"}, // epoch rocks
|
|
|
|
|
{"5:2", LESS, "304:2"}, // so big epoch?
|
|
|
|
|
{"25:2", GREATER, "3:2"}, // 25 > 3, obviously
|
|
|
|
|
{"1:2:123", LESS, "1:12:3"}, // 12 > 2
|
|
|
|
|
{"1.2-5", LESS, "1.2-3-5"}, // 1.2 < 1.2-3
|
|
|
|
|
{"5.10.0", GREATER, "5.005"}, // preceding zeroes don't matters
|
|
|
|
|
{"3a9.8", LESS, "3.10.2"}, // letters are before all letter symbols
|
|
|
|
|
{"3a9.8", GREATER, "3~10"}, // but after the tilde
|
|
|
|
|
{"1.4+OOo3.0.0~", LESS, "1.4+OOo3.0.0-4"}, // another tilde check
|
|
|
|
|
{"2.4.7-1", LESS, "2.4.7-z"}, // revision comparing
|
|
|
|
|
{"1.002-1+b2", GREATER, "1.00"}, // whatever...
|
|
|
|
|
// Tests imported from tests/rpmvercmp.at
|
|
|
|
|
{"1.0", EQUAL, "1.0"},
|
|
|
|
|
{"1.0", LESS, "2.0"},
|
|
|
|
|
{"2.0", GREATER, "1.0"},
|
|
|
|
|
|
|
|
|
|
{"2.0.1", EQUAL, "2.0.1"},
|
|
|
|
|
{"2.0", LESS, "2.0.1"},
|
|
|
|
|
{"2.0.1", GREATER, "2.0"},
|
|
|
|
|
|
|
|
|
|
{"2.0.1a", EQUAL, "2.0.1a"},
|
|
|
|
|
{"2.0.1a", GREATER, "2.0.1"},
|
|
|
|
|
{"2.0.1", LESS, "2.0.1a"},
|
|
|
|
|
|
|
|
|
|
{"5.5p1", EQUAL, "5.5p1"},
|
|
|
|
|
{"5.5p1", LESS, "5.5p2"},
|
|
|
|
|
{"5.5p2", GREATER, "5.5p1"},
|
|
|
|
|
|
|
|
|
|
{"5.5p10", EQUAL, "5.5p10"},
|
|
|
|
|
{"5.5p1", LESS, "5.5p10"},
|
|
|
|
|
{"5.5p10", GREATER, "5.5p1"},
|
|
|
|
|
|
|
|
|
|
{"10xyz", LESS, "10.1xyz"},
|
|
|
|
|
{"10.1xyz", GREATER, "10xyz"},
|
|
|
|
|
|
|
|
|
|
{"xyz10", EQUAL, "xyz10"},
|
|
|
|
|
{"xyz10", LESS, "xyz10.1"},
|
|
|
|
|
{"xyz10.1", GREATER, "xyz10"},
|
|
|
|
|
|
|
|
|
|
{"xyz.4", EQUAL, "xyz.4"},
|
|
|
|
|
{"xyz.4", LESS, "8"},
|
|
|
|
|
{"8", GREATER, "xyz.4"},
|
|
|
|
|
{"xyz.4", LESS, "2"},
|
|
|
|
|
{"2", GREATER, "xyz.4"},
|
|
|
|
|
|
|
|
|
|
{"5.5p2", LESS, "5.6p1"},
|
|
|
|
|
{"5.6p1", GREATER, "5.5p2"},
|
|
|
|
|
|
|
|
|
|
{"5.6p1", LESS, "6.5p1"},
|
|
|
|
|
{"6.5p1", GREATER, "5.6p1"},
|
|
|
|
|
|
|
|
|
|
{"6.0.rc1", GREATER, "6.0"},
|
|
|
|
|
{"6.0", LESS, "6.0.rc1"},
|
|
|
|
|
|
|
|
|
|
{"10b2", GREATER, "10a1"},
|
|
|
|
|
{"10a2", LESS, "10b2"},
|
|
|
|
|
|
|
|
|
|
{"1.0aa", EQUAL, "1.0aa"},
|
|
|
|
|
{"1.0a", LESS, "1.0aa"},
|
|
|
|
|
{"1.0aa", GREATER, "1.0a"},
|
|
|
|
|
|
|
|
|
|
{"10.0001", EQUAL, "10.0001"},
|
|
|
|
|
{"10.0001", EQUAL, "10.1"},
|
|
|
|
|
{"10.1", EQUAL, "10.0001"},
|
|
|
|
|
{"10.0001", LESS, "10.0039"},
|
|
|
|
|
{"10.0039", GREATER, "10.0001"},
|
|
|
|
|
|
|
|
|
|
{"4.999.9", LESS, "5.0"},
|
|
|
|
|
{"5.0", GREATER, "4.999.9"},
|
|
|
|
|
|
|
|
|
|
{"20101121", EQUAL, "20101121"},
|
|
|
|
|
{"20101121", LESS, "20101122"},
|
|
|
|
|
{"20101122", GREATER, "20101121"},
|
|
|
|
|
|
|
|
|
|
{"2_0", EQUAL, "2_0"},
|
|
|
|
|
{"2.0", EQUAL, "2_0"},
|
|
|
|
|
{"2_0", EQUAL, "2.0"},
|
|
|
|
|
|
|
|
|
|
// RhBug:178798 case
|
|
|
|
|
{"a", EQUAL, "a"},
|
|
|
|
|
{"a+", EQUAL, "a+"},
|
|
|
|
|
{"a+", EQUAL, "a_"},
|
|
|
|
|
{"a_", EQUAL, "a+"},
|
|
|
|
|
{"+a", EQUAL, "+a"},
|
|
|
|
|
{"+a", EQUAL, "_a"},
|
|
|
|
|
{"_a", EQUAL, "+a"},
|
|
|
|
|
{"+_", EQUAL, "+_"},
|
|
|
|
|
{"_+", EQUAL, "+_"},
|
|
|
|
|
{"_+", EQUAL, "_+"},
|
|
|
|
|
{"+", EQUAL, "_"},
|
|
|
|
|
{"_", EQUAL, "+"},
|
|
|
|
|
|
|
|
|
|
// Basic testcases for tilde sorting
|
|
|
|
|
{"1.0~rc1", EQUAL, "1.0~rc1"},
|
|
|
|
|
{"1.0~rc1", LESS, "1.0"},
|
|
|
|
|
{"1.0", GREATER, "1.0~rc1"},
|
|
|
|
|
{"1.0~rc1", LESS, "1.0~rc2"},
|
|
|
|
|
{"1.0~rc2", GREATER, "1.0~rc1"},
|
|
|
|
|
{"1.0~rc1~git123", EQUAL, "1.0~rc1~git123"},
|
|
|
|
|
{"1.0~rc1~git123", LESS, "1.0~rc1"},
|
|
|
|
|
{"1.0~rc1", GREATER, "1.0~rc1~git123"},
|
|
|
|
|
|
|
|
|
|
// These are included here to document current, arguably buggy behaviors
|
|
|
|
|
// for reference purposes and for easy checking against unintended
|
|
|
|
|
// behavior changes.
|
|
|
|
|
//
|
|
|
|
|
// AT_BANNER([RPM version comparison oddities])
|
|
|
|
|
// RhBug:811992 case
|
|
|
|
|
// {"1b.fc17", EQUAL, "1b.fc17"},
|
|
|
|
|
// {"1b.fc17", LESS, "1.fc17"},
|
|
|
|
|
// {"1.fc17", GREATER, "1b.fc17"},
|
|
|
|
|
// {"1g.fc17", EQUAL, "1g.fc17"},
|
|
|
|
|
// {"1g.fc17", GREATER, "1.fc17"},
|
|
|
|
|
// {"1.fc17", LESS, "1g.fc17"},
|
|
|
|
|
|
|
|
|
|
// Non-ascii characters are considered equal so these are all the same, eh...
|
|
|
|
|
// {"1.1.α", EQUAL, "1.1.α"},
|
|
|
|
|
// {"1.1.α", EQUAL, "1.1.β"},
|
|
|
|
|
// {"1.1.β", EQUAL, "1.1.α"},
|
|
|
|
|
// {"1.1.αα", EQUAL, "1.1.α"},
|
|
|
|
|
// {"1.1.α", EQUAL, "1.1.ββ"},
|
|
|
|
|
// {"1.1.ββ", EQUAL, "1.1.αα"},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var (
|
|
|
|
|