github.com/Lephar/snapd@v0.0.0-20210825215435-c7fba9cef4d2/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 "io/ioutil" 25 "os" 26 "os/user" 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/features" 34 "github.com/snapcore/snapd/osutil" 35 "github.com/snapcore/snapd/osutil/sys" 36 "github.com/snapcore/snapd/snap" 37 "github.com/snapcore/snapd/testutil" 38 ) 39 40 func Test(t *testing.T) { TestingT(t) } 41 42 type HTestSuite struct { 43 testutil.BaseTest 44 } 45 46 var _ = Suite(&HTestSuite{}) 47 48 var mockYaml = []byte(`name: snapname 49 version: 1.0 50 apps: 51 app: 52 command: run-app 53 hooks: 54 configure: 55 `) 56 57 var mockSnapInfo = &snap.Info{ 58 SuggestedName: "foo", 59 Version: "1.0", 60 SideInfo: snap.SideInfo{ 61 Revision: snap.R(17), 62 }, 63 } 64 var mockClassicSnapInfo = &snap.Info{ 65 SuggestedName: "foo", 66 Version: "1.0", 67 SideInfo: snap.SideInfo{ 68 Revision: snap.R(17), 69 }, 70 Confinement: snap.ClassicConfinement, 71 } 72 73 func (s *HTestSuite) SetUpTest(c *C) { 74 s.BaseTest.SetUpTest(c) 75 s.BaseTest.AddCleanup(snap.MockSanitizePlugsSlots(func(snapInfo *snap.Info) {})) 76 } 77 78 func (s *HTestSuite) TearDownTest(c *C) { 79 s.BaseTest.TearDownTest(c) 80 } 81 82 func (ts *HTestSuite) TestBasic(c *C) { 83 env := basicEnv(mockSnapInfo) 84 c.Assert(env, DeepEquals, osutil.Environment{ 85 "SNAP": fmt.Sprintf("%s/foo/17", dirs.CoreSnapMountDir), 86 "SNAP_COMMON": "/var/snap/foo/common", 87 "SNAP_DATA": "/var/snap/foo/17", 88 "SNAP_NAME": "foo", 89 "SNAP_INSTANCE_NAME": "foo", 90 "SNAP_INSTANCE_KEY": "", 91 "SNAP_VERSION": "1.0", 92 "SNAP_REVISION": "17", 93 "SNAP_ARCH": arch.DpkgArchitecture(), 94 "SNAP_LIBRARY_PATH": "/var/lib/snapd/lib/gl:/var/lib/snapd/lib/gl32:/var/lib/snapd/void", 95 "SNAP_REEXEC": "", 96 }) 97 } 98 99 func (ts *HTestSuite) TestUser(c *C) { 100 env := userEnv(mockSnapInfo, "/root") 101 c.Assert(env, DeepEquals, osutil.Environment{ 102 "SNAP_USER_COMMON": "/root/snap/foo/common", 103 "SNAP_USER_DATA": "/root/snap/foo/17", 104 "HOME": "/root/snap/foo/17", 105 "XDG_RUNTIME_DIR": fmt.Sprintf("/run/user/%d/snap.foo", sys.Geteuid()), 106 "SNAP_REAL_HOME": "/root", 107 }) 108 } 109 110 func (ts *HTestSuite) TestUserForClassicConfinement(c *C) { 111 dirs.SetRootDir(c.MkDir()) 112 defer dirs.SetRootDir("/") 113 c.Assert(os.MkdirAll(dirs.FeaturesDir, 0755), IsNil) 114 115 // With the classic-preserves-xdg-runtime-dir feature disabled the snap 116 // per-user environment contains an override for XDG_RUNTIME_DIR. 117 env := userEnv(mockClassicSnapInfo, "/root") 118 c.Assert(env, DeepEquals, osutil.Environment{ 119 // NOTE: Both HOME and XDG_RUNTIME_DIR are not defined here. 120 "SNAP_USER_COMMON": "/root/snap/foo/common", 121 "SNAP_USER_DATA": "/root/snap/foo/17", 122 "XDG_RUNTIME_DIR": fmt.Sprintf(dirs.GlobalRootDir+"/run/user/%d/snap.foo", sys.Geteuid()), 123 "SNAP_REAL_HOME": "/root", 124 }) 125 126 // With the classic-preserves-xdg-runtime-dir feature enabled the snap 127 // per-user environment contains no overrides for XDG_RUNTIME_DIR. 128 f := features.ClassicPreservesXdgRuntimeDir 129 c.Assert(ioutil.WriteFile(f.ControlFile(), nil, 0644), IsNil) 130 env = userEnv(mockClassicSnapInfo, "/root") 131 c.Assert(env, DeepEquals, osutil.Environment{ 132 // NOTE: Both HOME and XDG_RUNTIME_DIR are not defined here. 133 "SNAP_USER_COMMON": "/root/snap/foo/common", 134 "SNAP_USER_DATA": "/root/snap/foo/17", 135 "SNAP_REAL_HOME": "/root", 136 }) 137 } 138 139 func (s *HTestSuite) TestSnapRunSnapExecEnv(c *C) { 140 info, err := snap.InfoFromSnapYaml(mockYaml) 141 c.Assert(err, IsNil) 142 info.SideInfo.Revision = snap.R(42) 143 144 usr, err := user.Current() 145 c.Assert(err, IsNil) 146 147 homeEnv := os.Getenv("HOME") 148 defer os.Setenv("HOME", homeEnv) 149 150 for _, withHomeEnv := range []bool{true, false} { 151 if !withHomeEnv { 152 os.Setenv("HOME", "") 153 } 154 155 env := snapEnv(info) 156 c.Assert(env, DeepEquals, osutil.Environment{ 157 "SNAP": fmt.Sprintf("%s/snapname/42", dirs.CoreSnapMountDir), 158 "SNAP_COMMON": "/var/snap/snapname/common", 159 "SNAP_DATA": "/var/snap/snapname/42", 160 "SNAP_NAME": "snapname", 161 "SNAP_INSTANCE_NAME": "snapname", 162 "SNAP_INSTANCE_KEY": "", 163 "SNAP_VERSION": "1.0", 164 "SNAP_REVISION": "42", 165 "SNAP_ARCH": arch.DpkgArchitecture(), 166 "SNAP_LIBRARY_PATH": "/var/lib/snapd/lib/gl:/var/lib/snapd/lib/gl32:/var/lib/snapd/void", 167 "SNAP_REEXEC": "", 168 "SNAP_USER_COMMON": fmt.Sprintf("%s/snap/snapname/common", usr.HomeDir), 169 "SNAP_USER_DATA": fmt.Sprintf("%s/snap/snapname/42", usr.HomeDir), 170 "HOME": fmt.Sprintf("%s/snap/snapname/42", usr.HomeDir), 171 "XDG_RUNTIME_DIR": fmt.Sprintf("/run/user/%d/snap.snapname", sys.Geteuid()), 172 "SNAP_REAL_HOME": usr.HomeDir, 173 }) 174 } 175 } 176 177 func (s *HTestSuite) TestParallelInstallSnapRunSnapExecEnv(c *C) { 178 info, err := snap.InfoFromSnapYaml(mockYaml) 179 c.Assert(err, IsNil) 180 info.SideInfo.Revision = snap.R(42) 181 182 usr, err := user.Current() 183 c.Assert(err, IsNil) 184 185 homeEnv := os.Getenv("HOME") 186 defer os.Setenv("HOME", homeEnv) 187 188 // pretend it's snapname_foo 189 info.InstanceKey = "foo" 190 191 for _, withHomeEnv := range []bool{true, false} { 192 if !withHomeEnv { 193 os.Setenv("HOME", "") 194 } 195 196 env := snapEnv(info) 197 c.Check(env, DeepEquals, osutil.Environment{ 198 // Those are mapped to snap-specific directories by 199 // mount namespace setup 200 "SNAP": fmt.Sprintf("%s/snapname/42", dirs.CoreSnapMountDir), 201 "SNAP_COMMON": "/var/snap/snapname/common", 202 "SNAP_DATA": "/var/snap/snapname/42", 203 "SNAP_NAME": "snapname", 204 "SNAP_INSTANCE_NAME": "snapname_foo", 205 "SNAP_INSTANCE_KEY": "foo", 206 "SNAP_VERSION": "1.0", 207 "SNAP_REVISION": "42", 208 "SNAP_ARCH": arch.DpkgArchitecture(), 209 "SNAP_LIBRARY_PATH": "/var/lib/snapd/lib/gl:/var/lib/snapd/lib/gl32:/var/lib/snapd/void", 210 "SNAP_REEXEC": "", 211 // User's data directories are not mapped to 212 // snap-specific ones 213 "SNAP_USER_COMMON": fmt.Sprintf("%s/snap/snapname_foo/common", usr.HomeDir), 214 "SNAP_USER_DATA": fmt.Sprintf("%s/snap/snapname_foo/42", usr.HomeDir), 215 "HOME": fmt.Sprintf("%s/snap/snapname_foo/42", usr.HomeDir), 216 "XDG_RUNTIME_DIR": fmt.Sprintf("/run/user/%d/snap.snapname_foo", sys.Geteuid()), 217 "SNAP_REAL_HOME": usr.HomeDir, 218 }) 219 } 220 } 221 222 func (ts *HTestSuite) TestParallelInstallUser(c *C) { 223 info := *mockSnapInfo 224 info.InstanceKey = "bar" 225 env := userEnv(&info, "/root") 226 227 c.Assert(env, DeepEquals, osutil.Environment{ 228 "SNAP_USER_COMMON": "/root/snap/foo_bar/common", 229 "SNAP_USER_DATA": "/root/snap/foo_bar/17", 230 "HOME": "/root/snap/foo_bar/17", 231 "XDG_RUNTIME_DIR": fmt.Sprintf("/run/user/%d/snap.foo_bar", sys.Geteuid()), 232 "SNAP_REAL_HOME": "/root", 233 }) 234 } 235 236 func (ts *HTestSuite) TestParallelInstallUserForClassicConfinement(c *C) { 237 dirs.SetRootDir(c.MkDir()) 238 defer dirs.SetRootDir("/") 239 c.Assert(os.MkdirAll(dirs.FeaturesDir, 0755), IsNil) 240 241 info := *mockClassicSnapInfo 242 info.InstanceKey = "bar" 243 244 // With the classic-preserves-xdg-runtime-dir feature disabled the snap 245 // per-user environment contains an override for XDG_RUNTIME_DIR. 246 env := userEnv(&info, "/root") 247 c.Assert(env, DeepEquals, osutil.Environment{ 248 "SNAP_USER_COMMON": "/root/snap/foo_bar/common", 249 "SNAP_USER_DATA": "/root/snap/foo_bar/17", 250 "XDG_RUNTIME_DIR": fmt.Sprintf(dirs.GlobalRootDir+"/run/user/%d/snap.foo_bar", sys.Geteuid()), 251 "SNAP_REAL_HOME": "/root", 252 }) 253 254 // With the classic-preserves-xdg-runtime-dir feature enabled the snap 255 // per-user environment contains no overrides for XDG_RUNTIME_DIR. 256 f := features.ClassicPreservesXdgRuntimeDir 257 c.Assert(ioutil.WriteFile(f.ControlFile(), nil, 0644), IsNil) 258 env = userEnv(&info, "/root") 259 c.Assert(env, DeepEquals, osutil.Environment{ 260 // NOTE, Both HOME and XDG_RUNTIME_DIR are not defined here. 261 "SNAP_USER_COMMON": "/root/snap/foo_bar/common", 262 "SNAP_USER_DATA": "/root/snap/foo_bar/17", 263 "SNAP_REAL_HOME": "/root", 264 }) 265 } 266 267 func (s *HTestSuite) TestExtendEnvForRunForNonClassic(c *C) { 268 env := osutil.Environment{"TMPDIR": "/var/tmp"} 269 270 ExtendEnvForRun(env, mockSnapInfo) 271 272 c.Assert(env["SNAP_NAME"], Equals, "foo") 273 c.Assert(env["SNAP_COMMON"], Equals, "/var/snap/foo/common") 274 c.Assert(env["SNAP_DATA"], Equals, "/var/snap/foo/17") 275 276 c.Assert(env["TMPDIR"], Equals, "/var/tmp") 277 } 278 279 func (s *HTestSuite) TestExtendEnvForRunForClassic(c *C) { 280 env := osutil.Environment{"TMPDIR": "/var/tmp"} 281 282 ExtendEnvForRun(env, mockClassicSnapInfo) 283 284 c.Assert(env["SNAP_NAME"], Equals, "foo") 285 c.Assert(env["SNAP_COMMON"], Equals, "/var/snap/foo/common") 286 c.Assert(env["SNAP_DATA"], Equals, "/var/snap/foo/17") 287 288 c.Assert(env["TMPDIR"], Equals, "/var/tmp") 289 }