github.com/rigado/snapd@v2.42.5-go-mod+incompatible/snap/snapenv/snapenv_test.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2014-2015 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 snapenv 21 22 import ( 23 "fmt" 24 "os" 25 "os/user" 26 "strings" 27 "testing" 28 29 . "gopkg.in/check.v1" 30 31 "github.com/snapcore/snapd/arch" 32 "github.com/snapcore/snapd/dirs" 33 "github.com/snapcore/snapd/osutil/sys" 34 "github.com/snapcore/snapd/snap" 35 "github.com/snapcore/snapd/testutil" 36 ) 37 38 func Test(t *testing.T) { TestingT(t) } 39 40 type HTestSuite struct { 41 testutil.BaseTest 42 } 43 44 var _ = Suite(&HTestSuite{}) 45 46 var mockYaml = []byte(`name: snapname 47 version: 1.0 48 apps: 49 app: 50 command: run-app 51 hooks: 52 configure: 53 `) 54 55 var mockSnapInfo = &snap.Info{ 56 SuggestedName: "foo", 57 Version: "1.0", 58 SideInfo: snap.SideInfo{ 59 Revision: snap.R(17), 60 }, 61 } 62 var mockClassicSnapInfo = &snap.Info{ 63 SuggestedName: "foo", 64 Version: "1.0", 65 SideInfo: snap.SideInfo{ 66 Revision: snap.R(17), 67 }, 68 Confinement: snap.ClassicConfinement, 69 } 70 71 func (s *HTestSuite) SetUpTest(c *C) { 72 s.BaseTest.SetUpTest(c) 73 s.BaseTest.AddCleanup(snap.MockSanitizePlugsSlots(func(snapInfo *snap.Info) {})) 74 } 75 76 func (s *HTestSuite) TearDownTest(c *C) { 77 s.BaseTest.TearDownTest(c) 78 } 79 80 func (ts *HTestSuite) TestBasic(c *C) { 81 env := basicEnv(mockSnapInfo) 82 83 c.Assert(env, DeepEquals, map[string]string{ 84 "SNAP": fmt.Sprintf("%s/foo/17", dirs.CoreSnapMountDir), 85 "SNAP_ARCH": arch.DpkgArchitecture(), 86 "SNAP_COMMON": "/var/snap/foo/common", 87 "SNAP_DATA": "/var/snap/foo/17", 88 "SNAP_LIBRARY_PATH": "/var/lib/snapd/lib/gl:/var/lib/snapd/lib/gl32:/var/lib/snapd/void", 89 "SNAP_NAME": "foo", 90 "SNAP_INSTANCE_NAME": "foo", 91 "SNAP_INSTANCE_KEY": "", 92 "SNAP_REEXEC": "", 93 "SNAP_REVISION": "17", 94 "SNAP_VERSION": "1.0", 95 }) 96 97 } 98 99 func (ts *HTestSuite) TestUser(c *C) { 100 env := userEnv(mockSnapInfo, "/root") 101 102 c.Assert(env, DeepEquals, map[string]string{ 103 "HOME": "/root/snap/foo/17", 104 "SNAP_USER_COMMON": "/root/snap/foo/common", 105 "SNAP_USER_DATA": "/root/snap/foo/17", 106 "XDG_RUNTIME_DIR": fmt.Sprintf("/run/user/%d/snap.foo", sys.Geteuid()), 107 }) 108 } 109 110 func (ts *HTestSuite) TestUserForClassicConfinement(c *C) { 111 env := userEnv(mockClassicSnapInfo, "/root") 112 113 c.Assert(env, DeepEquals, map[string]string{ 114 // NOTE HOME Is absent! we no longer override it 115 "SNAP_USER_COMMON": "/root/snap/foo/common", 116 "SNAP_USER_DATA": "/root/snap/foo/17", 117 "XDG_RUNTIME_DIR": fmt.Sprintf("/run/user/%d/snap.foo", sys.Geteuid()), 118 }) 119 } 120 121 func (s *HTestSuite) TestSnapRunSnapExecEnv(c *C) { 122 info, err := snap.InfoFromSnapYaml(mockYaml) 123 c.Assert(err, IsNil) 124 info.SideInfo.Revision = snap.R(42) 125 126 usr, err := user.Current() 127 c.Assert(err, IsNil) 128 129 homeEnv := os.Getenv("HOME") 130 defer os.Setenv("HOME", homeEnv) 131 132 for _, withHomeEnv := range []bool{true, false} { 133 if !withHomeEnv { 134 os.Setenv("HOME", "") 135 } 136 137 env := snapEnv(info) 138 c.Check(env, DeepEquals, map[string]string{ 139 "SNAP_ARCH": arch.DpkgArchitecture(), 140 "SNAP_LIBRARY_PATH": "/var/lib/snapd/lib/gl:/var/lib/snapd/lib/gl32:/var/lib/snapd/void", 141 "SNAP_NAME": "snapname", 142 "SNAP_INSTANCE_NAME": "snapname", 143 "SNAP_INSTANCE_KEY": "", 144 "SNAP_REEXEC": "", 145 "SNAP_REVISION": "42", 146 "SNAP_VERSION": "1.0", 147 148 "SNAP": fmt.Sprintf("%s/snapname/42", dirs.CoreSnapMountDir), 149 "SNAP_COMMON": "/var/snap/snapname/common", 150 "SNAP_DATA": "/var/snap/snapname/42", 151 152 "SNAP_USER_COMMON": fmt.Sprintf("%s/snap/snapname/common", usr.HomeDir), 153 "SNAP_USER_DATA": fmt.Sprintf("%s/snap/snapname/42", usr.HomeDir), 154 "XDG_RUNTIME_DIR": fmt.Sprintf("/run/user/%d/snap.snapname", sys.Geteuid()), 155 "HOME": fmt.Sprintf("%s/snap/snapname/42", usr.HomeDir), 156 }) 157 } 158 } 159 160 func (s *HTestSuite) TestParallelInstallSnapRunSnapExecEnv(c *C) { 161 info, err := snap.InfoFromSnapYaml(mockYaml) 162 c.Assert(err, IsNil) 163 info.SideInfo.Revision = snap.R(42) 164 165 usr, err := user.Current() 166 c.Assert(err, IsNil) 167 168 homeEnv := os.Getenv("HOME") 169 defer os.Setenv("HOME", homeEnv) 170 171 // pretend it's snapname_foo 172 info.InstanceKey = "foo" 173 174 for _, withHomeEnv := range []bool{true, false} { 175 if !withHomeEnv { 176 os.Setenv("HOME", "") 177 } 178 179 env := snapEnv(info) 180 c.Check(env, DeepEquals, map[string]string{ 181 "SNAP_ARCH": arch.DpkgArchitecture(), 182 "SNAP_LIBRARY_PATH": "/var/lib/snapd/lib/gl:/var/lib/snapd/lib/gl32:/var/lib/snapd/void", 183 "SNAP_NAME": "snapname", 184 "SNAP_INSTANCE_NAME": "snapname_foo", 185 "SNAP_INSTANCE_KEY": "foo", 186 "SNAP_REEXEC": "", 187 "SNAP_REVISION": "42", 188 "SNAP_VERSION": "1.0", 189 190 // Those are mapped to snap-specific directories by 191 // mount namespace setup 192 "SNAP": fmt.Sprintf("%s/snapname/42", dirs.CoreSnapMountDir), 193 "SNAP_COMMON": "/var/snap/snapname/common", 194 "SNAP_DATA": "/var/snap/snapname/42", 195 196 // User's data directories are not mapped to 197 // snap-specific ones 198 "SNAP_USER_COMMON": fmt.Sprintf("%s/snap/snapname_foo/common", usr.HomeDir), 199 "SNAP_USER_DATA": fmt.Sprintf("%s/snap/snapname_foo/42", usr.HomeDir), 200 "XDG_RUNTIME_DIR": fmt.Sprintf("/run/user/%d/snap.snapname_foo", sys.Geteuid()), 201 "HOME": fmt.Sprintf("%s/snap/snapname_foo/42", usr.HomeDir), 202 }) 203 } 204 } 205 206 func (ts *HTestSuite) TestParallelInstallUser(c *C) { 207 info := *mockSnapInfo 208 info.InstanceKey = "bar" 209 env := userEnv(&info, "/root") 210 211 c.Assert(env, DeepEquals, map[string]string{ 212 "HOME": "/root/snap/foo_bar/17", 213 "SNAP_USER_COMMON": "/root/snap/foo_bar/common", 214 "SNAP_USER_DATA": "/root/snap/foo_bar/17", 215 "XDG_RUNTIME_DIR": fmt.Sprintf("/run/user/%d/snap.foo_bar", sys.Geteuid()), 216 }) 217 } 218 219 func (ts *HTestSuite) TestParallelInstallUserForClassicConfinement(c *C) { 220 info := *mockClassicSnapInfo 221 info.InstanceKey = "bar" 222 env := userEnv(&info, "/root") 223 224 c.Assert(env, DeepEquals, map[string]string{ 225 // NOTE HOME Is absent! we no longer override it 226 "SNAP_USER_COMMON": "/root/snap/foo_bar/common", 227 "SNAP_USER_DATA": "/root/snap/foo_bar/17", 228 "XDG_RUNTIME_DIR": fmt.Sprintf("/run/user/%d/snap.foo_bar", sys.Geteuid()), 229 }) 230 } 231 232 func envValue(env []string, key string) (bool, string) { 233 for _, item := range env { 234 if strings.HasPrefix(item, key+"=") { 235 return true, strings.SplitN(item, "=", 2)[1] 236 } 237 } 238 return false, "" 239 } 240 241 func (s *HTestSuite) TestExtraEnvForExecEnv(c *C) { 242 info, err := snap.InfoFromSnapYaml(mockYaml) 243 c.Assert(err, IsNil) 244 info.SideInfo.Revision = snap.R(42) 245 246 env := ExecEnv(info, map[string]string{"FOO": "BAR"}) 247 found, val := envValue(env, "FOO") 248 c.Assert(found, Equals, true) 249 c.Assert(val, Equals, "BAR") 250 } 251 252 func setenvWithReset(s *HTestSuite, key string, val string) { 253 tmpdirEnv, tmpdirFound := os.LookupEnv("TMPDIR") 254 os.Setenv("TMPDIR", "/var/tmp") 255 if tmpdirFound { 256 s.AddCleanup(func() { os.Setenv("TMPDIR", tmpdirEnv) }) 257 } else { 258 s.AddCleanup(func() { os.Unsetenv("TMPDIR") }) 259 } 260 } 261 262 func (s *HTestSuite) TestExecEnvNoRenameTMPDIRForNonClassic(c *C) { 263 setenvWithReset(s, "TMPDIR", "/var/tmp") 264 265 env := ExecEnv(mockSnapInfo, map[string]string{}) 266 267 found, val := envValue(env, "TMPDIR") 268 c.Assert(found, Equals, true) 269 c.Assert(val, Equals, "/var/tmp") 270 271 found, _ = envValue(env, PreservedUnsafePrefix+"TMPDIR") 272 c.Assert(found, Equals, false) 273 } 274 275 func (s *HTestSuite) TestExecEnvRenameTMPDIRForClassic(c *C) { 276 setenvWithReset(s, "TMPDIR", "/var/tmp") 277 278 env := ExecEnv(mockClassicSnapInfo, map[string]string{}) 279 280 found, _ := envValue(env, "TMPDIR") 281 c.Assert(found, Equals, false) 282 283 found, val := envValue(env, PreservedUnsafePrefix+"TMPDIR") 284 c.Assert(found, Equals, true) 285 c.Assert(val, Equals, "/var/tmp") 286 }