github.com/Pankov404/juju@v0.0.0-20150703034450-be266991dceb/version/version_test.go (about) 1 // Copyright 2012, 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package version_test 5 6 import ( 7 "encoding/json" 8 "io/ioutil" 9 "path/filepath" 10 "runtime" 11 "strings" 12 13 jc "github.com/juju/testing/checkers" 14 gc "gopkg.in/check.v1" 15 "gopkg.in/mgo.v2/bson" 16 goyaml "gopkg.in/yaml.v1" 17 18 "github.com/juju/juju/testing" 19 "github.com/juju/juju/version" 20 ) 21 22 type suite struct { 23 testing.BaseSuite 24 } 25 26 var _ = gc.Suite(&suite{}) 27 28 // N.B. The FORCE-VERSION logic is tested in the environs package. 29 30 func (*suite) TestCompare(c *gc.C) { 31 cmpTests := []struct { 32 v1, v2 string 33 compare int 34 }{ 35 {"1.0.0", "1.0.0", 0}, 36 {"01.0.0", "1.0.0", 0}, 37 {"10.0.0", "9.0.0", 1}, 38 {"1.0.0", "1.0.1", -1}, 39 {"1.0.1", "1.0.0", 1}, 40 {"1.0.0", "1.1.0", -1}, 41 {"1.1.0", "1.0.0", 1}, 42 {"1.0.0", "2.0.0", -1}, 43 {"1.2-alpha1", "1.2.0", -1}, 44 {"1.2-alpha2", "1.2-alpha1", 1}, 45 {"1.2-alpha2.1", "1.2-alpha2", 1}, 46 {"1.2-alpha2.2", "1.2-alpha2.1", 1}, 47 {"1.2-beta1", "1.2-alpha1", 1}, 48 {"1.2-beta1", "1.2-alpha2.1", 1}, 49 {"1.2-beta1", "1.2.0", -1}, 50 {"1.2.1", "1.2.0", 1}, 51 {"2.0.0", "1.0.0", 1}, 52 {"2.0.0.0", "2.0.0", 0}, 53 {"2.0.0.0", "2.0.0.0", 0}, 54 {"2.0.0.1", "2.0.0.0", 1}, 55 {"2.0.1.10", "2.0.0.0", 1}, 56 {"2.0-_0", "2.0-00", 1}, 57 {"2.0-_0", "2.0.0", -1}, 58 {"2.0-_0", "2.0-alpha1.0", -1}, 59 {"2.0-_0", "1.999.0", 1}, 60 } 61 62 for i, test := range cmpTests { 63 c.Logf("test %d", i) 64 v1, err := version.Parse(test.v1) 65 c.Assert(err, jc.ErrorIsNil) 66 v2, err := version.Parse(test.v2) 67 c.Assert(err, jc.ErrorIsNil) 68 compare := v1.Compare(v2) 69 c.Check(compare, gc.Equals, test.compare) 70 // Check that reversing the operands has 71 // the expected result. 72 compare = v2.Compare(v1) 73 c.Check(compare, gc.Equals, -test.compare) 74 } 75 } 76 77 var parseTests = []struct { 78 v string 79 err string 80 expect version.Number 81 dev bool 82 }{{ 83 v: "0.0.0", 84 }, { 85 v: "0.0.1", 86 expect: version.Number{Major: 0, Minor: 0, Patch: 1}, 87 }, { 88 v: "0.0.2", 89 expect: version.Number{Major: 0, Minor: 0, Patch: 2}, 90 }, { 91 v: "0.1.0", 92 expect: version.Number{Major: 0, Minor: 1, Patch: 0}, 93 dev: true, 94 }, { 95 v: "0.2.3", 96 expect: version.Number{Major: 0, Minor: 2, Patch: 3}, 97 }, { 98 v: "1.0.0", 99 expect: version.Number{Major: 1, Minor: 0, Patch: 0}, 100 }, { 101 v: "10.234.3456", 102 expect: version.Number{Major: 10, Minor: 234, Patch: 3456}, 103 }, { 104 v: "10.234.3456.1", 105 expect: version.Number{Major: 10, Minor: 234, Patch: 3456, Build: 1}, 106 dev: true, 107 }, { 108 v: "10.234.3456.64", 109 expect: version.Number{Major: 10, Minor: 234, Patch: 3456, Build: 64}, 110 dev: true, 111 }, { 112 v: "10.235.3456", 113 expect: version.Number{Major: 10, Minor: 235, Patch: 3456}, 114 }, { 115 v: "1.21-alpha1", 116 expect: version.Number{Major: 1, Minor: 21, Patch: 1, Tag: "alpha"}, 117 dev: true, 118 }, { 119 v: "1.21-alpha1.1", 120 expect: version.Number{Major: 1, Minor: 21, Patch: 1, Tag: "alpha", Build: 1}, 121 dev: true, 122 }, { 123 v: "1.21.0", 124 expect: version.Number{Major: 1, Minor: 21}, 125 }, { 126 v: "1234567890.2.1", 127 err: "invalid version.*", 128 }, { 129 v: "0.2..1", 130 err: "invalid version.*", 131 }, { 132 v: "1.21.alpha1", 133 err: "invalid version.*", 134 }, { 135 v: "1.21-alpha", 136 err: "invalid version.*", 137 }, { 138 v: "1.21-alpha1beta", 139 err: "invalid version.*", 140 }, { 141 v: "1.21-alpha-dev", 142 err: "invalid version.*", 143 }} 144 145 func (*suite) TestParse(c *gc.C) { 146 for i, test := range parseTests { 147 c.Logf("test %d", i) 148 got, err := version.Parse(test.v) 149 if test.err != "" { 150 c.Assert(err, gc.ErrorMatches, test.err) 151 } else { 152 c.Assert(err, jc.ErrorIsNil) 153 c.Assert(got, gc.Equals, test.expect) 154 c.Check(got.IsDev(), gc.Equals, test.dev) 155 c.Check(got.String(), gc.Equals, test.v) 156 } 157 } 158 } 159 160 func binaryVersion(major, minor, patch, build int, tag, series, arch string) version.Binary { 161 return version.Binary{ 162 Number: version.Number{ 163 Major: major, 164 Minor: minor, 165 Patch: patch, 166 Build: build, 167 Tag: tag, 168 }, 169 Series: series, 170 Arch: arch, 171 OS: version.Ubuntu, 172 } 173 } 174 175 func (*suite) TestParseBinary(c *gc.C) { 176 parseBinaryTests := []struct { 177 v string 178 err string 179 expect version.Binary 180 }{{ 181 v: "1.2.3-trusty-amd64", 182 expect: binaryVersion(1, 2, 3, 0, "", "trusty", "amd64"), 183 }, { 184 v: "1.2.3.4-trusty-amd64", 185 expect: binaryVersion(1, 2, 3, 4, "", "trusty", "amd64"), 186 }, { 187 v: "1.2-alpha3-trusty-amd64", 188 expect: binaryVersion(1, 2, 3, 0, "alpha", "trusty", "amd64"), 189 }, { 190 v: "1.2-alpha3.4-trusty-amd64", 191 expect: binaryVersion(1, 2, 3, 4, "alpha", "trusty", "amd64"), 192 }, { 193 v: "1.2.3", 194 err: "invalid binary version.*", 195 }, { 196 v: "1.2-beta1", 197 err: "invalid binary version.*", 198 }, { 199 v: "1.2.3--amd64", 200 err: "invalid binary version.*", 201 }, { 202 v: "1.2.3-trusty-", 203 err: "invalid binary version.*", 204 }} 205 206 for i, test := range parseBinaryTests { 207 c.Logf("test 1: %d", i) 208 got, err := version.ParseBinary(test.v) 209 if test.err != "" { 210 c.Assert(err, gc.ErrorMatches, test.err) 211 } else { 212 c.Assert(err, jc.ErrorIsNil) 213 c.Assert(got, gc.Equals, test.expect) 214 } 215 } 216 217 for i, test := range parseTests { 218 c.Logf("test 2: %d", i) 219 v := test.v + "-trusty-amd64" 220 got, err := version.ParseBinary(v) 221 expect := version.Binary{ 222 Number: test.expect, 223 Series: "trusty", 224 Arch: "amd64", 225 OS: version.Ubuntu, 226 } 227 if test.err != "" { 228 c.Assert(err, gc.ErrorMatches, strings.Replace(test.err, "version", "binary version", 1)) 229 } else { 230 c.Assert(err, jc.ErrorIsNil) 231 c.Assert(got, gc.Equals, expect) 232 c.Check(got.IsDev(), gc.Equals, test.dev) 233 } 234 } 235 } 236 237 var marshallers = []struct { 238 name string 239 marshal func(interface{}) ([]byte, error) 240 unmarshal func([]byte, interface{}) error 241 }{{ 242 "json", 243 json.Marshal, 244 json.Unmarshal, 245 }, { 246 "bson", 247 bson.Marshal, 248 bson.Unmarshal, 249 }, { 250 "yaml", 251 goyaml.Marshal, 252 goyaml.Unmarshal, 253 }} 254 255 func (*suite) TestBinaryMarshalUnmarshal(c *gc.C) { 256 for _, m := range marshallers { 257 c.Logf("encoding %v", m.name) 258 type doc struct { 259 Version *version.Binary 260 } 261 // Work around goyaml bug #1096149 262 // SetYAML is not called for non-pointer fields. 263 bp := version.MustParseBinary("1.2.3-trusty-amd64") 264 v := doc{&bp} 265 data, err := m.marshal(&v) 266 c.Assert(err, jc.ErrorIsNil) 267 var bv doc 268 err = m.unmarshal(data, &bv) 269 c.Assert(err, jc.ErrorIsNil) 270 c.Assert(bv, gc.DeepEquals, v) 271 } 272 } 273 274 func (*suite) TestNumberMarshalUnmarshal(c *gc.C) { 275 for _, m := range marshallers { 276 c.Logf("encoding %v", m.name) 277 type doc struct { 278 Version *version.Number 279 } 280 // Work around goyaml bug #1096149 281 // SetYAML is not called for non-pointer fields. 282 np := version.MustParse("1.2.3") 283 v := doc{&np} 284 data, err := m.marshal(&v) 285 c.Assert(err, jc.ErrorIsNil) 286 var nv doc 287 err = m.unmarshal(data, &nv) 288 c.Assert(err, jc.ErrorIsNil) 289 c.Assert(nv, gc.DeepEquals, v) 290 } 291 } 292 293 func (*suite) TestParseMajorMinor(c *gc.C) { 294 parseMajorMinorTests := []struct { 295 v string 296 err string 297 expectMajor int 298 expectMinor int 299 }{{ 300 v: "1.2", 301 expectMajor: 1, 302 expectMinor: 2, 303 }, { 304 v: "1", 305 expectMajor: 1, 306 expectMinor: -1, 307 }, { 308 v: "1.2.3", 309 err: "invalid major.minor version number 1.2.3", 310 }, { 311 v: "blah", 312 err: `invalid major version number blah: strconv.ParseInt: parsing "blah": invalid syntax`, 313 }} 314 315 for i, test := range parseMajorMinorTests { 316 c.Logf("test %d", i) 317 major, minor, err := version.ParseMajorMinor(test.v) 318 if test.err != "" { 319 c.Check(err, gc.ErrorMatches, test.err) 320 } else { 321 c.Check(err, jc.ErrorIsNil) 322 c.Check(major, gc.Equals, test.expectMajor) 323 c.Check(minor, gc.Equals, test.expectMinor) 324 } 325 } 326 } 327 328 func (s *suite) TestUseFastLXC(c *gc.C) { 329 for i, test := range []struct { 330 message string 331 releaseContent string 332 expected string 333 }{{ 334 message: "missing release file", 335 }, { 336 message: "OS release file is missing ID", 337 releaseContent: "some junk\nand more junk", 338 }, { 339 message: "precise release", 340 releaseContent: ` 341 NAME="Ubuntu" 342 VERSION="12.04 LTS, Precise" 343 ID=ubuntu 344 ID_LIKE=debian 345 PRETTY_NAME="Ubuntu 12.04.3 LTS" 346 VERSION_ID="12.04" 347 `, 348 expected: "12.04", 349 }, { 350 message: "trusty release", 351 releaseContent: ` 352 NAME="Ubuntu" 353 VERSION="14.04.1 LTS, Trusty Tahr" 354 ID=ubuntu 355 ID_LIKE=debian 356 PRETTY_NAME="Ubuntu 14.04.1 LTS" 357 VERSION_ID="14.04" 358 `, 359 expected: "14.04", 360 }, { 361 message: "minimal trusty release", 362 releaseContent: ` 363 ID=ubuntu 364 VERSION_ID="14.04" 365 `, 366 expected: "14.04", 367 }, { 368 message: "minimal unstable unicorn", 369 releaseContent: ` 370 ID=ubuntu 371 VERSION_ID="14.10" 372 `, 373 expected: "14.10", 374 }, { 375 message: "minimal jaunty", 376 releaseContent: ` 377 ID=ubuntu 378 VERSION_ID="9.10" 379 `, 380 expected: "9.10", 381 }} { 382 c.Logf("%v: %v", i, test.message) 383 filename := filepath.Join(c.MkDir(), "os-release") 384 s.PatchValue(version.OSReleaseFile, filename) 385 if test.releaseContent != "" { 386 err := ioutil.WriteFile(filename, []byte(test.releaseContent+"\n"), 0644) 387 c.Assert(err, jc.ErrorIsNil) 388 } 389 value := version.ReleaseVersion() 390 c.Assert(value, gc.Equals, test.expected) 391 } 392 } 393 394 func (s *suite) TestCompiler(c *gc.C) { 395 c.Assert(version.Compiler, gc.Equals, runtime.Compiler) 396 }