github.com/altoros/juju-vmware@v0.0.0-20150312064031-f19ae857ccca/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  }