go.mondoo.com/cnquery@v0.0.0-20231005093811-59568235f6ea/providers/core/resources/versions/rpm/version_test.go (about) 1 // Copyright 2016 clair authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package rpm 16 17 import ( 18 "testing" 19 20 "github.com/stretchr/testify/assert" 21 ) 22 23 const ( 24 LESS = -1 25 EQUAL = 0 26 GREATER = 1 27 ) 28 29 func TestParse(t *testing.T) { 30 cases := []struct { 31 str string 32 ver version 33 err bool 34 }{ 35 // Test 0 36 {"0", version{epoch: 0, version: "0", release: ""}, false}, 37 {"0:0", version{epoch: 0, version: "0", release: ""}, false}, 38 {"0:0-", version{epoch: 0, version: "0", release: ""}, false}, 39 {"0:0-0", version{epoch: 0, version: "0", release: "0"}, false}, 40 {"0:0.0-0.0", version{epoch: 0, version: "0.0", release: "0.0"}, false}, 41 // Test epoched 42 {"1:0", version{epoch: 1, version: "0", release: ""}, false}, 43 {"5:1", version{epoch: 5, version: "1", release: ""}, false}, 44 // Test multiple hyphens 45 {"0:0-0-0", version{epoch: 0, version: "0", release: "0-0"}, false}, 46 {"0:0-0-0-0", version{epoch: 0, version: "0", release: "0-0-0"}, false}, 47 // Test multiple colons 48 {"0:0:0-0", version{epoch: 0, version: "0:0", release: "0"}, false}, 49 {"0:0:0:0-0", version{epoch: 0, version: "0:0:0", release: "0"}, false}, 50 // Test multiple hyphens and colons 51 {"0:0:0-0-0", version{epoch: 0, version: "0:0", release: "0-0"}, false}, 52 {"0:0-0:0-0", version{epoch: 0, version: "0", release: "0:0-0"}, false}, 53 // Test version with leading and trailing spaces 54 {" 0:0-1", version{epoch: 0, version: "0", release: "1"}, false}, 55 {"0:0-1 ", version{epoch: 0, version: "0", release: "1"}, false}, 56 {" 0:0-1 ", version{epoch: 0, version: "0", release: "1"}, false}, 57 // Test empty version 58 {"", version{}, true}, 59 {" ", version{}, true}, 60 {"0:", version{}, true}, 61 // Test version with embedded spaces 62 {"0:0 0-1", version{}, true}, 63 // Test version with negative epoch 64 {"-1:0-1", version{}, true}, 65 // Test invalid characters in epoch 66 {"a:0-0", version{}, true}, 67 {"A:0-0", version{}, true}, 68 // Test version not starting with a digit 69 {"0:abc3-0", version{epoch: 0, version: "abc3", release: "0"}, false}, 70 } 71 for _, c := range cases { 72 v, err := newVersion(c.str) 73 74 if c.err { 75 assert.Error(t, err, "When parsing '%s'", c.str) 76 } else { 77 assert.Nil(t, err, "When parsing '%s'", c.str) 78 } 79 assert.Equal(t, c.ver, v, "When parsing '%s'", c.str) 80 } 81 } 82 83 func TestParseAndCompare(t *testing.T) { 84 cases := []struct { 85 v1 string 86 expected int 87 v2 string 88 }{ 89 // Oracle Linux corner cases. 90 {"2.9.1-6.0.1.el7_2.3", GREATER, "2.9.1-6.el7_2.3"}, 91 {"3.10.0-327.28.3.el7", GREATER, "3.10.0-327.el7"}, 92 {"3.14.3-23.3.el6_8", GREATER, "3.14.3-23.el6_7"}, 93 {"2.23.2-22.el7_1", LESS, "2.23.2-22.el7_1.1"}, 94 95 // Tests imported from tests/rpmvercmp.at 96 {"1.0", EQUAL, "1.0"}, 97 {"1.0", LESS, "2.0"}, 98 {"2.0", GREATER, "1.0"}, 99 {"2.0.1", EQUAL, "2.0.1"}, 100 {"2.0", LESS, "2.0.1"}, 101 {"2.0.1", GREATER, "2.0"}, 102 {"2.0.1a", EQUAL, "2.0.1a"}, 103 {"2.0.1a", GREATER, "2.0.1"}, 104 {"2.0.1", LESS, "2.0.1a"}, 105 {"5.5p1", EQUAL, "5.5p1"}, 106 {"5.5p1", LESS, "5.5p2"}, 107 {"5.5p2", GREATER, "5.5p1"}, 108 {"5.5p10", EQUAL, "5.5p10"}, 109 {"5.5p1", LESS, "5.5p10"}, 110 {"5.5p10", GREATER, "5.5p1"}, 111 {"10xyz", LESS, "10.1xyz"}, 112 {"10.1xyz", GREATER, "10xyz"}, 113 {"xyz10", EQUAL, "xyz10"}, 114 {"xyz10", LESS, "xyz10.1"}, 115 {"xyz10.1", GREATER, "xyz10"}, 116 {"xyz.4", EQUAL, "xyz.4"}, 117 {"xyz.4", LESS, "8"}, 118 {"8", GREATER, "xyz.4"}, 119 {"xyz.4", LESS, "2"}, 120 {"2", GREATER, "xyz.4"}, 121 {"5.5p2", LESS, "5.6p1"}, 122 {"5.6p1", GREATER, "5.5p2"}, 123 {"5.6p1", LESS, "6.5p1"}, 124 {"6.5p1", GREATER, "5.6p1"}, 125 {"6.0.rc1", GREATER, "6.0"}, 126 {"6.0", LESS, "6.0.rc1"}, 127 {"10b2", GREATER, "10a1"}, 128 {"10a2", LESS, "10b2"}, 129 {"1.0aa", EQUAL, "1.0aa"}, 130 {"1.0a", LESS, "1.0aa"}, 131 {"1.0aa", GREATER, "1.0a"}, 132 {"10.0001", EQUAL, "10.0001"}, 133 {"10.0001", EQUAL, "10.1"}, 134 {"10.1", EQUAL, "10.0001"}, 135 {"10.0001", LESS, "10.0039"}, 136 {"10.0039", GREATER, "10.0001"}, 137 {"4.999.9", LESS, "5.0"}, 138 {"5.0", GREATER, "4.999.9"}, 139 {"20101121", EQUAL, "20101121"}, 140 {"20101121", LESS, "20101122"}, 141 {"20101122", GREATER, "20101121"}, 142 {"2_0", EQUAL, "2_0"}, 143 {"2.0", EQUAL, "2_0"}, 144 {"2_0", EQUAL, "2.0"}, 145 {"a", EQUAL, "a"}, 146 {"a+", EQUAL, "a+"}, 147 {"a+", EQUAL, "a_"}, 148 {"a_", EQUAL, "a+"}, 149 {"+a", EQUAL, "+a"}, 150 {"+a", EQUAL, "_a"}, 151 {"_a", EQUAL, "+a"}, 152 {"+_", EQUAL, "+_"}, 153 {"_+", EQUAL, "+_"}, 154 {"_+", EQUAL, "_+"}, 155 {"+", EQUAL, "_"}, 156 {"_", EQUAL, "+"}, 157 {"1.0~rc1", EQUAL, "1.0~rc1"}, 158 {"1.0~rc1", LESS, "1.0"}, 159 {"1.0", GREATER, "1.0~rc1"}, 160 {"1.0~rc1", LESS, "1.0~rc2"}, 161 {"1.0~rc2", GREATER, "1.0~rc1"}, 162 {"1.0~rc1~git123", EQUAL, "1.0~rc1~git123"}, 163 {"1.0~rc1~git123", LESS, "1.0~rc1"}, 164 {"1.0~rc1", GREATER, "1.0~rc1~git123"}, 165 {"1~", GREATER, "1~~"}, 166 {"2~", GREATER, "1"}, 167 {"1.0", GREATER, "1.0-~"}, 168 {"1.0", LESS, "1.0-1~"}, 169 {"~", GREATER, "~~"}, 170 } 171 172 var ( 173 p Parser 174 cmp int 175 err error 176 ) 177 for _, c := range cases { 178 cmp, err = p.Compare(c.v1, c.v2) 179 assert.Nil(t, err) 180 assert.Equal(t, c.expected, cmp, "%s vs. %s, = %d, expected %d", c.v1, c.v2, cmp, c.expected) 181 182 cmp, err = p.Compare(c.v2, c.v1) 183 assert.Nil(t, err) 184 assert.Equal(t, -c.expected, cmp, "%s vs. %s, = %d, expected %d", c.v2, c.v1, cmp, -c.expected) 185 } 186 }