github.com/kubiko/snapd@v0.0.0-20201013125620-d4f3094d9ddf/snap/naming/validate_test.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2016 Canonical Ltd 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 3 as 8 * published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 * 18 */ 19 20 package naming_test 21 22 import ( 23 "fmt" 24 . "gopkg.in/check.v1" 25 26 "github.com/snapcore/snapd/snap/naming" 27 28 "github.com/snapcore/snapd/testutil" 29 ) 30 31 type ValidateSuite struct { 32 testutil.BaseTest 33 } 34 35 var _ = Suite(&ValidateSuite{}) 36 37 func (s *ValidateSuite) SetUpTest(c *C) { 38 s.BaseTest.SetUpTest(c) 39 } 40 41 func (s *ValidateSuite) TearDownTest(c *C) { 42 s.BaseTest.TearDownTest(c) 43 } 44 45 func (s *ValidateSuite) TestValidateName(c *C) { 46 validNames := []string{ 47 "aa", "aaa", "aaaa", 48 "a-a", "aa-a", "a-aa", "a-b-c", 49 "a0", "a-0", "a-0a", 50 "01game", "1-or-2", 51 // a regexp stresser 52 "u-94903713687486543234157734673284536758", 53 } 54 for _, name := range validNames { 55 err := naming.ValidateSnap(name) 56 c.Assert(err, IsNil) 57 } 58 invalidNames := []string{ 59 // name cannot be empty 60 "", 61 // too short (min 2 chars) 62 "a", 63 // names cannot be too long 64 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", 65 "xxxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxx", 66 "1111111111111111111111111111111111111111x", 67 "x1111111111111111111111111111111111111111", 68 "x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x", 69 // a regexp stresser 70 "u-9490371368748654323415773467328453675-", 71 // dashes alone are not a name 72 "-", "--", 73 // double dashes in a name are not allowed 74 "a--a", 75 // name should not end with a dash 76 "a-", 77 // name cannot have any spaces in it 78 "a ", " a", "a a", 79 // a number alone is not a name 80 "0", "123", 81 // identifier must be plain ASCII 82 "日本語", "한글", "ру́сский язы́к", 83 } 84 for _, name := range invalidNames { 85 err := naming.ValidateSnap(name) 86 c.Assert(err, ErrorMatches, `invalid snap name: ".*"`) 87 } 88 } 89 90 func (s *ValidateSuite) TestValidateInstanceName(c *C) { 91 validNames := []string{ 92 // plain names are also valid instance names 93 "aa", "aaa", "aaaa", 94 "a-a", "aa-a", "a-aa", "a-b-c", 95 // snap instance 96 "foo_bar", 97 "foo_0123456789", 98 "01game_0123456789", 99 "foo_1", "foo_1234abcd", 100 } 101 for _, name := range validNames { 102 err := naming.ValidateInstance(name) 103 c.Assert(err, IsNil) 104 } 105 invalidNames := []string{ 106 // invalid names are also invalid instance names, just a few 107 // samples 108 "", 109 "a", 110 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", 111 "xxxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxx", 112 "a--a", 113 "a-", 114 "a ", " a", "a a", 115 "_", 116 "ру́сский_язы́к", 117 } 118 for _, name := range invalidNames { 119 err := naming.ValidateInstance(name) 120 c.Assert(err, ErrorMatches, `invalid snap name: ".*"`) 121 } 122 invalidInstanceKeys := []string{ 123 // the snap names are valid, but instance keys are not 124 "foo_", "foo_1-23", "foo_01234567890", "foo_123_456", 125 "foo__bar", 126 } 127 for _, name := range invalidInstanceKeys { 128 err := naming.ValidateInstance(name) 129 c.Assert(err, ErrorMatches, `invalid instance key: ".*"`) 130 } 131 132 } 133 134 func (s *ValidateSuite) TestValidateHookName(c *C) { 135 validHooks := []string{ 136 "a", 137 "aaa", 138 "a-a", 139 "aa-a", 140 "a-aa", 141 "a-b-c", 142 "valid", 143 } 144 for _, hook := range validHooks { 145 err := naming.ValidateHook(hook) 146 c.Assert(err, IsNil) 147 } 148 invalidHooks := []string{ 149 "", 150 "a a", 151 "a--a", 152 "-a", 153 "a-", 154 "0", 155 "123", 156 "123abc", 157 "日本語", 158 } 159 for _, hook := range invalidHooks { 160 err := naming.ValidateHook(hook) 161 c.Assert(err, ErrorMatches, `invalid hook name: ".*"`) 162 } 163 // Regression test for https://bugs.launchpad.net/snapd/+bug/1638988 164 c.Assert(naming.ValidateHook("connect-plug-i2c"), IsNil) 165 } 166 167 func (s *ValidateSuite) TestValidateAppName(c *C) { 168 validAppNames := []string{ 169 "1", "a", "aa", "aaa", "aaaa", "Aa", "aA", "1a", "a1", "1-a", "a-1", 170 "a-a", "aa-a", "a-aa", "a-b-c", "0a-a", "a-0a", 171 } 172 for _, name := range validAppNames { 173 c.Check(naming.ValidateApp(name), IsNil) 174 } 175 invalidAppNames := []string{ 176 "", "-", "--", "a--a", "a-", "a ", " a", "a a", "日本語", "한글", 177 "ру́сский язы́к", "ໄຂ່ອີສເຕີ້", ":a", "a:", "a:a", "_a", "a_", "a_a", 178 } 179 for _, name := range invalidAppNames { 180 err := naming.ValidateApp(name) 181 c.Assert(err, ErrorMatches, `invalid app name: ".*"`) 182 } 183 } 184 185 func (s *ValidateSuite) TestValidateAlias(c *C) { 186 validAliases := []string{ 187 "a", "aa", "aaa", "aaaa", 188 "a-a", "aa-a", "a-aa", "a-b-c", 189 "a0", "a-0", "a-0a", 190 "a_a", "aa_a", "a_aa", "a_b_c", 191 "a0", "a_0", "a_0a", 192 "01game", "1-or-2", 193 "0.1game", "1_or_2", 194 } 195 for _, alias := range validAliases { 196 err := naming.ValidateAlias(alias) 197 c.Assert(err, IsNil) 198 } 199 invalidAliases := []string{ 200 "", 201 "_foo", 202 "-foo", 203 ".foo", 204 "foo$", 205 } 206 for _, alias := range invalidAliases { 207 err := naming.ValidateAlias(alias) 208 c.Assert(err, ErrorMatches, `invalid alias name: ".*"`) 209 } 210 } 211 212 func (s *ValidateSuite) TestValidateSocketName(c *C) { 213 validNames := []string{ 214 "a", "aa", "aaa", "aaaa", 215 "a-a", "aa-a", "a-aa", "a-b-c", 216 "a0", "a-0", "a-0a", 217 "01game", "1-or-2", 218 } 219 for _, name := range validNames { 220 err := naming.ValidateSocket(name) 221 c.Assert(err, IsNil) 222 } 223 invalidNames := []string{ 224 // name cannot be empty 225 "", 226 // dashes alone are not a name 227 "-", "--", 228 // double dashes in a name are not allowed 229 "a--a", 230 // name should not end with a dash 231 "a-", 232 // name cannot have any spaces in it 233 "a ", " a", "a a", 234 // a number alone is not a name 235 "0", "123", 236 // identifier must be plain ASCII 237 "日本語", "한글", "ру́сский язы́к", 238 // no null chars in the string are allowed 239 "aa-a\000-b", 240 } 241 for _, name := range invalidNames { 242 err := naming.ValidateSocket(name) 243 c.Assert(err, ErrorMatches, `invalid socket name: ".*"`) 244 } 245 } 246 247 func (s *ValidateSuite) TestValidateSlotPlugInterfaceName(c *C) { 248 valid := []string{ 249 "a", 250 "aaa", 251 "a-a", 252 "aa-a", 253 "a-aa", 254 "a-b-c", 255 "valid", 256 "valid-123", 257 } 258 for _, name := range valid { 259 err := naming.ValidateSlot(name) 260 c.Assert(err, IsNil) 261 err = naming.ValidatePlug(name) 262 c.Assert(err, IsNil) 263 err = naming.ValidateInterface(name) 264 c.Assert(err, IsNil) 265 } 266 invalid := []string{ 267 "", 268 "a a", 269 "a--a", 270 "-a", 271 "a-", 272 "0", 273 "123", 274 "123abc", 275 "日本語", 276 } 277 for _, name := range invalid { 278 err := naming.ValidateSlot(name) 279 c.Assert(err, ErrorMatches, `invalid slot name: ".*"`) 280 err = naming.ValidatePlug(name) 281 c.Assert(err, ErrorMatches, `invalid plug name: ".*"`) 282 err = naming.ValidateInterface(name) 283 c.Assert(err, ErrorMatches, `invalid interface name: ".*"`) 284 } 285 } 286 287 func (s *ValidateSuite) TestValidateSnapID(c *C) { 288 c.Check(naming.ValidateSnapID("buPKUD3TKqCOgLEjjHx5kSiCpIs5cMuQ"), IsNil) 289 290 invalid := []string{ 291 "", 292 "buPKUD3TKqC", 293 "buPKUD3TKqCOgLE-jHx5kSiCpIs5cMuQ", 294 "buPKUD3TKqCOgLEjjHx5kSiCpIs5cMuQxxx", 295 } 296 for _, id := range invalid { 297 err := naming.ValidateSnapID(id) 298 c.Check(err, ErrorMatches, fmt.Sprintf("invalid snap-id: %q", id)) 299 } 300 } 301 302 func (s *ValidateSuite) TestValidateSecurityTag(c *C) { 303 // valid snap names, snap instances, app names and hook names are accepted. 304 c.Check(naming.ValidateSecurityTag("snap.pkg.app"), IsNil) 305 c.Check(naming.ValidateSecurityTag("snap.pkg.hook.configure"), IsNil) 306 c.Check(naming.ValidateSecurityTag("snap.pkg_key.app"), IsNil) 307 c.Check(naming.ValidateSecurityTag("snap.pkg_key.hook.configure"), IsNil) 308 309 // invalid format is rejected 310 c.Check(naming.ValidateSecurityTag("snap.pkg_key.app.surprise"), ErrorMatches, "invalid security tag") 311 c.Check(naming.ValidateSecurityTag("snap.pkg_key.hook.configure.surprise"), ErrorMatches, "invalid security tag") 312 313 // invalid snap and app names are rejected. 314 c.Check(naming.ValidateSecurityTag("snap._.app"), ErrorMatches, "invalid security tag") 315 c.Check(naming.ValidateSecurityTag("snap.pkg._"), ErrorMatches, "invalid security tag") 316 317 // invalid number of components are rejected. 318 c.Check(naming.ValidateSecurityTag("snap.pkg.hook.surprise."), ErrorMatches, "invalid security tag") 319 c.Check(naming.ValidateSecurityTag("snap.pkg.hook."), ErrorMatches, "invalid security tag") 320 c.Check(naming.ValidateSecurityTag("snap.pkg.hook"), IsNil) // Perhaps somewhat unexpectedly, this tag is valid. 321 c.Check(naming.ValidateSecurityTag("snap.pkg.app.surprise"), ErrorMatches, "invalid security tag") 322 c.Check(naming.ValidateSecurityTag("snap.pkg."), ErrorMatches, "invalid security tag") 323 c.Check(naming.ValidateSecurityTag("snap.pkg"), ErrorMatches, "invalid security tag") 324 c.Check(naming.ValidateSecurityTag("snap."), ErrorMatches, "invalid security tag") 325 c.Check(naming.ValidateSecurityTag("snap"), ErrorMatches, "invalid security tag") 326 }