github.com/juju/charm/v11@v11.2.0/base_test.go (about) 1 // Copyright 2020 Canonical Ltd. 2 // Licensed under the LGPLv3, see LICENCE file for details. 3 4 package charm_test 5 6 import ( 7 "encoding/json" 8 "strings" 9 10 "github.com/juju/os/v2" 11 "github.com/juju/testing" 12 jc "github.com/juju/testing/checkers" 13 "github.com/juju/utils/v3/arch" 14 gc "gopkg.in/check.v1" 15 16 "github.com/juju/charm/v11" 17 ) 18 19 type baseSuite struct { 20 testing.CleanupSuite 21 } 22 23 var _ = gc.Suite(&baseSuite{}) 24 25 func (s *baseSuite) TestParseBase(c *gc.C) { 26 tests := []struct { 27 str string 28 parsedBase charm.Base 29 err string 30 }{ 31 { 32 str: "ubuntu", 33 parsedBase: charm.Base{}, 34 err: `base string must contain exactly one @. "ubuntu" not valid`, 35 }, { 36 str: "windows", 37 parsedBase: charm.Base{}, 38 err: `base string must contain exactly one @. "windows" not valid`, 39 }, { 40 str: "mythicalos@channel", 41 parsedBase: charm.Base{}, 42 err: `invalid base string "mythicalos@channel": os "mythicalos" not valid`, 43 }, { 44 str: "ubuntu@20.04/stable", 45 parsedBase: charm.Base{Name: strings.ToLower(os.Ubuntu.String()), Channel: mustParseChannel("20.04/stable")}, 46 }, { 47 str: "windows@win10/stable", 48 parsedBase: charm.Base{Name: strings.ToLower(os.Windows.String()), Channel: mustParseChannel("win10/stable")}, 49 }, { 50 str: "ubuntu@20.04/edge", 51 parsedBase: charm.Base{Name: strings.ToLower(os.Ubuntu.String()), Channel: mustParseChannel("20.04/edge")}, 52 }, 53 } 54 for i, v := range tests { 55 comment := gc.Commentf("test %d", i) 56 s, err := charm.ParseBase(v.str) 57 if v.err != "" { 58 c.Check(err, gc.ErrorMatches, v.err, comment) 59 } else { 60 c.Check(err, jc.ErrorIsNil, comment) 61 } 62 c.Check(s, jc.DeepEquals, v.parsedBase, comment) 63 } 64 } 65 66 func (s *baseSuite) TestParseBaseWithArchitectures(c *gc.C) { 67 tests := []struct { 68 str string 69 baseString string 70 archs []string 71 parsedBase charm.Base 72 err string 73 }{ 74 { 75 baseString: "ubuntu@", 76 str: "ubuntu on amd64", 77 archs: []string{"amd64"}, 78 parsedBase: charm.Base{}, 79 err: `invalid base string "ubuntu@" with architectures "amd64": channel not valid`, 80 }, { 81 baseString: "windows@", 82 str: "windows", 83 parsedBase: charm.Base{}, 84 err: `invalid base string "windows@": channel not valid`, 85 }, { 86 baseString: "mythicalos@channel", 87 str: "mythicalos", 88 parsedBase: charm.Base{}, 89 err: `invalid base string "mythicalos@channel": os "mythicalos" not valid`, 90 }, { 91 baseString: "ubuntu@20.04/stable", 92 archs: []string{arch.AMD64, "ppc64"}, 93 str: "ubuntu@20.04/stable on amd64, ppc64el", 94 parsedBase: charm.Base{ 95 Name: strings.ToLower(os.Ubuntu.String()), 96 Channel: mustParseChannel("20.04/stable"), 97 Architectures: []string{arch.AMD64, arch.PPC64EL}}, 98 }, { 99 baseString: "windows@win10/stable", 100 archs: []string{"testme"}, 101 str: "windows@win10/stable", 102 parsedBase: charm.Base{}, 103 err: `invalid base string "windows@win10/stable" with architectures "testme": architecture "testme" not valid`, 104 }, 105 } 106 for i, v := range tests { 107 comment := gc.Commentf("test %d", i) 108 s, err := charm.ParseBase(v.baseString, v.archs...) 109 if v.err != "" { 110 c.Check(err, gc.ErrorMatches, v.err, comment) 111 } else { 112 c.Check(err, jc.ErrorIsNil, comment) 113 } 114 c.Check(s, jc.DeepEquals, v.parsedBase, comment) 115 } 116 } 117 118 func (s *baseSuite) TestStringifyBase(c *gc.C) { 119 tests := []struct { 120 base charm.Base 121 str string 122 }{ 123 { 124 base: charm.Base{Name: strings.ToLower(os.Ubuntu.String()), Channel: mustParseChannel("20.04/stable")}, 125 str: "ubuntu@20.04/stable", 126 }, { 127 base: charm.Base{Name: strings.ToLower(os.Windows.String()), Channel: mustParseChannel("win10/stable")}, 128 str: "windows@win10/stable", 129 }, { 130 base: charm.Base{Name: strings.ToLower(os.Ubuntu.String()), Channel: mustParseChannel("20.04/edge")}, 131 str: "ubuntu@20.04/edge", 132 }, { 133 base: charm.Base{ 134 Name: strings.ToLower(os.Ubuntu.String()), 135 Channel: mustParseChannel("20.04/stable"), 136 Architectures: []string{arch.AMD64}, 137 }, 138 str: "ubuntu@20.04/stable on amd64", 139 }, { 140 base: charm.Base{ 141 Name: strings.ToLower(os.Ubuntu.String()), 142 Channel: mustParseChannel("20.04/stable"), 143 Architectures: []string{arch.AMD64, arch.PPC64EL}, 144 }, 145 str: "ubuntu@20.04/stable on amd64, ppc64el", 146 }, 147 } 148 for i, v := range tests { 149 comment := gc.Commentf("test %d", i) 150 c.Assert(v.base.Validate(), jc.ErrorIsNil) 151 c.Assert(v.base.String(), gc.Equals, v.str, comment) 152 } 153 } 154 155 func (s *baseSuite) TestJSONEncoding(c *gc.C) { 156 sys := charm.Base{ 157 Name: "ubuntu", 158 Channel: mustParseChannel("20.04/stable"), 159 } 160 bytes, err := json.Marshal(sys) 161 c.Assert(err, jc.ErrorIsNil) 162 c.Assert(string(bytes), gc.Equals, `{"name":"ubuntu","channel":{"track":"20.04","risk":"stable"}}`) 163 sys2 := charm.Base{} 164 err = json.Unmarshal(bytes, &sys2) 165 c.Assert(err, jc.ErrorIsNil) 166 c.Assert(sys2, jc.DeepEquals, sys) 167 } 168 169 // MustParseChannel parses a given string or returns a panic. 170 // Used for unit tests. 171 func mustParseChannel(s string) charm.Channel { 172 c, err := charm.ParseChannelNormalize(s) 173 if err != nil { 174 panic(err) 175 } 176 return c 177 }