github.com/kubiko/snapd@v0.0.0-20201013125620-d4f3094d9ddf/cmd/snap-update-ns/bootstrap_test.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2017 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 main_test 21 22 import ( 23 . "gopkg.in/check.v1" 24 25 update "github.com/snapcore/snapd/cmd/snap-update-ns" 26 ) 27 28 type bootstrapSuite struct{} 29 30 var _ = Suite(&bootstrapSuite{}) 31 32 // Check that ValidateSnapName rejects "/" and "..". 33 func (s *bootstrapSuite) TestValidateInstanceName(c *C) { 34 validNames := []string{ 35 "aa", 36 "aa_a", 37 "hello-world", 38 "a123456789012345678901234567890123456789", 39 "a123456789012345678901234567890123456789_0123456789", 40 "hello-world_foo", 41 "foo_0123456789", 42 "foo_1234abcd", 43 "a123456789012345678901234567890123456789", 44 "a123456789012345678901234567890123456789_0123456789", 45 } 46 for _, name := range validNames { 47 c.Check(update.ValidateInstanceName(name), Equals, 0, Commentf("name %q should be valid but is not", name)) 48 } 49 50 invalidNames := []string{ 51 "", 52 "a", 53 "a_a", 54 "a123456789012345678901234567890123456789_01234567890", 55 "hello/world", 56 "hello..world", 57 "INVALID", 58 "-invalid", 59 "hello-world_", 60 "_foo", 61 "foo_01234567890", 62 "foo_123_456", 63 "foo__456", 64 "foo_", 65 "hello-world_foo_foo", 66 "foo01234567890012345678900123456789001234567890", 67 "foo01234567890012345678900123456789001234567890_foo", 68 "a123456789012345678901234567890123456789_0123456789_", 69 } 70 for _, name := range invalidNames { 71 c.Check(update.ValidateInstanceName(name), Equals, -1, Commentf("name %q should be invalid but is valid", name)) 72 } 73 74 } 75 76 // Test various cases of command line handling. 77 func (s *bootstrapSuite) TestProcessArguments(c *C) { 78 cases := []struct { 79 cmdline []string 80 snapName string 81 shouldSetNs bool 82 userFstab bool 83 uid uint 84 errPattern string 85 }{ 86 // Corrupted buffer is dealt with. 87 {[]string{}, "", false, false, 0, "argv0 is corrupted"}, 88 // When testing real bootstrap is identified and disabled. 89 {[]string{"argv0.test"}, "", false, false, 0, "bootstrap is not enabled while testing"}, 90 // Snap name is mandatory. 91 {[]string{"argv0"}, "", false, false, 0, "snap name not provided"}, 92 // Snap name is parsed correctly. 93 {[]string{"argv0", "snapname"}, "snapname", true, false, 0, ""}, 94 {[]string{"argv0", "snapname_instance"}, "snapname_instance", true, false, 0, ""}, 95 // Onlye one snap name is allowed. 96 {[]string{"argv0", "snapone", "snaptwo"}, "", false, false, 0, "too many positional arguments"}, 97 // Snap name is validated correctly. 98 {[]string{"argv0", ""}, "", false, false, 0, "snap name must contain at least one letter"}, 99 {[]string{"argv0", "in--valid"}, "", false, false, 0, "snap name cannot contain two consecutive dashes"}, 100 {[]string{"argv0", "invalid-"}, "", false, false, 0, "snap name cannot end with a dash"}, 101 {[]string{"argv0", "@invalid"}, "", false, false, 0, "snap name must use lower case letters, digits or dashes"}, 102 {[]string{"argv0", "INVALID"}, "", false, false, 0, "snap name must use lower case letters, digits or dashes"}, 103 {[]string{"argv0", "foo_01234567890"}, "", false, false, 0, "instance key must be shorter than 10 characters"}, 104 {[]string{"argv0", "foo_0123456_2"}, "", false, false, 0, "snap instance name can contain only one underscore"}, 105 // The option --from-snap-confine disables setns. 106 {[]string{"argv0", "--from-snap-confine", "snapname"}, "snapname", false, false, 0, ""}, 107 {[]string{"argv0", "snapname", "--from-snap-confine"}, "snapname", false, false, 0, ""}, 108 // The option --user-mounts switches to the real uid 109 {[]string{"argv0", "--user-mounts", "snapname"}, "snapname", false, true, 0, ""}, 110 // Unknown options are reported. 111 {[]string{"argv0", "-invalid"}, "", false, false, 0, "unsupported option"}, 112 {[]string{"argv0", "--option"}, "", false, false, 0, "unsupported option"}, 113 {[]string{"argv0", "--from-snap-confine", "-invalid", "snapname"}, "", false, false, 0, "unsupported option"}, 114 // The -u option can be used to specify the user id. 115 {[]string{"argv0", "snapname", "-u", "1234"}, "snapname", true, true, 1234, ""}, 116 {[]string{"argv0", "-u", "1234", "snapname"}, "snapname", true, true, 1234, ""}, 117 /* Empty user id is rejected. */ 118 {[]string{"argv0", "-u", "", "snapname"}, "", false, false, 0, "cannot parse user id"}, 119 /* Partially parsed values are rejected. */ 120 {[]string{"argv0", "-u", "1foo", "snapname"}, "", false, false, 0, "cannot parse user id"}, 121 /* Hexadecimal values are rejected. */ 122 {[]string{"argv0", "-u", "0x16", "snapname"}, "", false, false, 0, "cannot parse user id"}, 123 {[]string{"argv0", "-u", " 0x16", "snapname"}, "", false, false, 0, "cannot parse user id"}, 124 {[]string{"argv0", "-u", "0x16 ", "snapname"}, "", false, false, 0, "cannot parse user id"}, 125 {[]string{"argv0", "-u", " 0x16 ", "snapname"}, "", false, false, 0, "cannot parse user id"}, 126 /* Octal-looking values are parsed as decimal. */ 127 {[]string{"argv0", "-u", "042", "snapname"}, "snapname", true, true, 42, ""}, 128 /* Spaces around octal values is rejected. */ 129 {[]string{"argv0", "-u", " 042", "snapname"}, "", false, false, 0, "cannot parse user id"}, 130 {[]string{"argv0", "-u", "042 ", "snapname"}, "", false, false, 0, "cannot parse user id"}, 131 {[]string{"argv0", "-u", " 042 ", "snapname"}, "", false, false, 0, "cannot parse user id"}, 132 /* Space around the value is rejected. */ 133 {[]string{"argv0", "-u", "42 ", "snapname"}, "", false, false, 0, "cannot parse user id"}, 134 {[]string{"argv0", "-u", " 42", "snapname"}, "", false, false, 0, "cannot parse user id"}, 135 {[]string{"argv0", "-u", " 42 ", "snapname"}, "", false, false, 0, "cannot parse user id"}, 136 {[]string{"argv0", "-u", "\n42 ", "snapname"}, "", false, false, 0, "cannot parse user id"}, 137 {[]string{"argv0", "-u", "42\t", "snapname"}, "", false, false, 0, "cannot parse user id"}, 138 /* Negative values are rejected. */ 139 {[]string{"argv0", "-u", "-1", "snapname"}, "", false, false, 0, "user id cannot be negative"}, 140 /* The option -u requires an argument. */ 141 {[]string{"argv0", "snapname", "-u"}, "", false, false, 0, "-u requires an argument"}, 142 } 143 for _, tc := range cases { 144 update.ClearBootstrapError() 145 snapName, shouldSetNs, userFstab, uid := update.ProcessArguments(tc.cmdline) 146 err := update.BootstrapError() 147 comment := Commentf("failed with cmdline %q, expected error pattern %q, actual error %q", 148 tc.cmdline, tc.errPattern, err) 149 if tc.errPattern != "" { 150 c.Assert(err, ErrorMatches, tc.errPattern, comment) 151 } else { 152 c.Assert(err, IsNil, comment) 153 } 154 c.Check(snapName, Equals, tc.snapName, comment) 155 c.Check(shouldSetNs, Equals, tc.shouldSetNs, comment) 156 c.Check(userFstab, Equals, tc.userFstab, comment) 157 c.Check(uid, Equals, tc.uid, comment) 158 } 159 }