github.com/rigado/snapd@v2.42.5-go-mod+incompatible/usersession/autostart/autostart_test.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2018 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 autostart_test 21 22 import ( 23 "io/ioutil" 24 "os" 25 "os/user" 26 "path" 27 "path/filepath" 28 "strings" 29 "testing" 30 31 . "gopkg.in/check.v1" 32 33 "github.com/snapcore/snapd/dirs" 34 "github.com/snapcore/snapd/snap" 35 "github.com/snapcore/snapd/snap/snaptest" 36 "github.com/snapcore/snapd/testutil" 37 "github.com/snapcore/snapd/usersession/autostart" 38 ) 39 40 func Test(t *testing.T) { TestingT(t) } 41 42 type autostartSuite struct { 43 dir string 44 autostartDir string 45 userDir string 46 userCurrentRestore func() 47 } 48 49 var _ = Suite(&autostartSuite{}) 50 51 func (s *autostartSuite) SetUpTest(c *C) { 52 s.dir = c.MkDir() 53 dirs.SetRootDir(s.dir) 54 snap.MockSanitizePlugsSlots(func(snapInfo *snap.Info) {}) 55 56 s.userDir = path.Join(s.dir, "home") 57 s.autostartDir = path.Join(s.userDir, ".config", "autostart") 58 s.userCurrentRestore = autostart.MockUserCurrent(func() (*user.User, error) { 59 return &user.User{HomeDir: s.userDir}, nil 60 }) 61 62 err := os.MkdirAll(s.autostartDir, 0755) 63 c.Assert(err, IsNil) 64 } 65 66 func (s *autostartSuite) TearDownTest(c *C) { 67 s.dir = c.MkDir() 68 dirs.SetRootDir("/") 69 if s.userCurrentRestore != nil { 70 s.userCurrentRestore() 71 } 72 } 73 74 func (s *autostartSuite) TestLoadAutostartDesktopFile(c *C) { 75 allGood := `[Desktop Entry] 76 Exec=foo --bar 77 ` 78 allGoodWithFlags := `[Desktop Entry] 79 Exec=foo --bar "%%p" %U %D +%s %% 80 ` 81 noExec := `[Desktop Entry] 82 Type=Application 83 ` 84 emptyExec := `[Desktop Entry] 85 Exec= 86 ` 87 onlySpacesExec := `[Desktop Entry] 88 Exec= 89 ` 90 hidden := `[Desktop Entry] 91 Exec=foo --bar 92 Hidden=true 93 ` 94 hiddenFalse := `[Desktop Entry] 95 Exec=foo --bar 96 Hidden=false 97 ` 98 justGNOME := `[Desktop Entry] 99 Exec=foo --bar 100 OnlyShowIn=GNOME; 101 ` 102 notInGNOME := `[Desktop Entry] 103 Exec=foo --bar 104 NotShownIn=GNOME; 105 ` 106 notInGNOMEAndKDE := `[Desktop Entry] 107 Exec=foo --bar 108 NotShownIn=GNOME;KDE; 109 ` 110 hiddenGNOMEextension := `[Desktop Entry] 111 Exec=foo --bar 112 X-GNOME-Autostart-enabled=false 113 ` 114 GNOMEextension := `[Desktop Entry] 115 Exec=foo --bar 116 X-GNOME-Autostart-enabled=true 117 ` 118 119 for i, tc := range []struct { 120 in string 121 out string 122 err string 123 current string 124 }{{ 125 in: allGood, 126 out: "foo --bar", 127 }, { 128 in: noExec, 129 err: "Exec not found or invalid", 130 }, { 131 in: emptyExec, 132 err: "Exec not found or invalid", 133 }, { 134 in: onlySpacesExec, 135 err: "Exec not found or invalid", 136 }, { 137 in: allGoodWithFlags, 138 out: `foo --bar "%p" + %`, 139 }, { 140 in: hidden, 141 err: `desktop file is hidden`, 142 }, { 143 in: hiddenFalse, 144 out: `foo --bar`, 145 }, { 146 in: justGNOME, 147 out: "foo --bar", 148 current: "GNOME", 149 }, { 150 in: justGNOME, 151 current: "KDE", 152 err: `current desktop \["KDE"\] not included in \["GNOME"\]`, 153 }, { 154 in: notInGNOME, 155 current: "GNOME", 156 err: `current desktop \["GNOME"\] excluded by \["GNOME"\]`, 157 }, { 158 in: notInGNOME, 159 current: "KDE", 160 out: "foo --bar", 161 }, { 162 in: notInGNOMEAndKDE, 163 current: "XFCE", 164 out: "foo --bar", 165 }, { 166 in: hiddenGNOMEextension, 167 current: "KDE", 168 out: "foo --bar", 169 }, { 170 in: hiddenGNOMEextension, 171 current: "GNOME", 172 err: `desktop file is hidden by X-GNOME-Autostart-enabled extension`, 173 }, { 174 in: GNOMEextension, 175 current: "GNOME", 176 out: "foo --bar", 177 }, { 178 in: GNOMEextension, 179 current: "KDE", 180 out: "foo --bar", 181 }} { 182 c.Logf("tc %d", i) 183 184 path := filepath.Join(c.MkDir(), "foo.desktop") 185 err := ioutil.WriteFile(path, []byte(tc.in), 0644) 186 c.Assert(err, IsNil) 187 188 run := func() { 189 defer autostart.MockCurrentDesktop(tc.current)() 190 191 cmd, err := autostart.LoadAutostartDesktopFile(path) 192 if tc.err != "" { 193 c.Check(cmd, Equals, "") 194 c.Check(err, ErrorMatches, tc.err) 195 } else { 196 c.Check(err, IsNil) 197 c.Check(cmd, Equals, tc.out) 198 } 199 } 200 run() 201 } 202 } 203 204 var mockYaml = `name: snapname 205 version: 1.0 206 apps: 207 foo: 208 command: run-app 209 autostart: foo-stable.desktop 210 ` 211 212 func (s *autostartSuite) TestTryAutostartAppValid(c *C) { 213 si := snaptest.MockSnapCurrent(c, mockYaml, &snap.SideInfo{Revision: snap.R("x2")}) 214 215 appWrapperPath := si.Apps["foo"].WrapperPath() 216 err := os.MkdirAll(filepath.Dir(appWrapperPath), 0755) 217 c.Assert(err, IsNil) 218 219 appCmd := testutil.MockCommand(c, appWrapperPath, "") 220 defer appCmd.Restore() 221 222 fooDesktopFile := filepath.Join(s.autostartDir, "foo-stable.desktop") 223 writeFile(c, fooDesktopFile, 224 []byte(`[Desktop Entry] 225 Exec=this-is-ignored -a -b --foo="a b c" -z "dev" 226 `)) 227 228 cmd, err := autostart.AutostartCmd("snapname", fooDesktopFile) 229 c.Assert(err, IsNil) 230 c.Assert(cmd.Path, Equals, appWrapperPath) 231 232 err = cmd.Start() 233 c.Assert(err, IsNil) 234 cmd.Wait() 235 236 c.Assert(appCmd.Calls(), DeepEquals, 237 [][]string{ 238 { 239 filepath.Base(appWrapperPath), 240 "-a", 241 "-b", 242 "--foo=a b c", 243 "-z", 244 "dev", 245 }, 246 }) 247 } 248 249 func (s *autostartSuite) TestTryAutostartAppNoMatchingApp(c *C) { 250 snaptest.MockSnapCurrent(c, mockYaml, &snap.SideInfo{Revision: snap.R("x2")}) 251 252 fooDesktopFile := filepath.Join(s.autostartDir, "foo-no-match.desktop") 253 writeFile(c, fooDesktopFile, 254 []byte(`[Desktop Entry] 255 Exec=this-is-ignored -a -b --foo="a b c" -z "dev" 256 `)) 257 258 cmd, err := autostart.AutostartCmd("snapname", fooDesktopFile) 259 c.Assert(cmd, IsNil) 260 c.Assert(err, ErrorMatches, `cannot match desktop file with snap snapname applications`) 261 } 262 263 func (s *autostartSuite) TestTryAutostartAppNoSnap(c *C) { 264 fooDesktopFile := filepath.Join(s.autostartDir, "foo-stable.desktop") 265 writeFile(c, fooDesktopFile, 266 []byte(`[Desktop Entry] 267 Exec=this-is-ignored -a -b --foo="a b c" -z "dev" 268 `)) 269 270 cmd, err := autostart.AutostartCmd("snapname", fooDesktopFile) 271 c.Assert(cmd, IsNil) 272 c.Assert(err, ErrorMatches, `cannot find current revision for snap snapname.*`) 273 } 274 275 func (s *autostartSuite) TestTryAutostartAppBadExec(c *C) { 276 snaptest.MockSnapCurrent(c, mockYaml, &snap.SideInfo{Revision: snap.R("x2")}) 277 278 fooDesktopFile := filepath.Join(s.autostartDir, "foo-stable.desktop") 279 writeFile(c, fooDesktopFile, 280 []byte(`[Desktop Entry] 281 Foo=bar 282 `)) 283 284 cmd, err := autostart.AutostartCmd("snapname", fooDesktopFile) 285 c.Assert(cmd, IsNil) 286 c.Assert(err, ErrorMatches, `cannot determine startup command for application foo in snap snapname: Exec not found or invalid`) 287 } 288 289 func writeFile(c *C, path string, content []byte) { 290 err := os.MkdirAll(filepath.Dir(path), 0755) 291 c.Assert(err, IsNil) 292 err = ioutil.WriteFile(path, content, 0644) 293 c.Assert(err, IsNil) 294 } 295 296 func (s *autostartSuite) TestTryAutostartMany(c *C) { 297 var mockYamlTemplate = `name: {snap} 298 version: 1.0 299 apps: 300 foo: 301 command: run-app 302 autostart: foo-stable.desktop 303 ` 304 305 snaptest.MockSnapCurrent(c, strings.Replace(mockYamlTemplate, "{snap}", "a-foo", -1), 306 &snap.SideInfo{Revision: snap.R("x2")}) 307 snaptest.MockSnapCurrent(c, strings.Replace(mockYamlTemplate, "{snap}", "b-foo", -1), 308 &snap.SideInfo{Revision: snap.R("x2")}) 309 writeFile(c, filepath.Join(s.userDir, "snap/a-foo/current/.config/autostart/foo-stable.desktop"), 310 []byte(`[Desktop Entry] 311 Foo=bar 312 `)) 313 writeFile(c, filepath.Join(s.userDir, "snap/b-foo/current/.config/autostart/no-match.desktop"), 314 []byte(`[Desktop Entry] 315 Exec=no-snap 316 `)) 317 writeFile(c, filepath.Join(s.userDir, "snap/c-foo/current/.config/autostart/no-snap.desktop"), 318 []byte(`[Desktop Entry] 319 Exec=no-snap 320 `)) 321 322 err := autostart.AutostartSessionApps() 323 c.Assert(err, NotNil) 324 c.Check(err, ErrorMatches, `- "foo-stable.desktop": cannot determine startup command for application foo in snap a-foo: Exec not found or invalid 325 - "no-match.desktop": cannot match desktop file with snap b-foo applications 326 - "no-snap.desktop": cannot find current revision for snap c-foo: readlink.*no such file or directory 327 `) 328 }