github.com/stolowski/snapd@v0.0.0-20210407085831-115137ce5a22/wrappers/dbus_test.go (about)

     1  // -*- Mode: Go; indent-tabs-mode: t -*-
     2  
     3  /*
     4   * Copyright (C) 2020 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 wrappers_test
    21  
    22  import (
    23  	"io/ioutil"
    24  	"os"
    25  	"path/filepath"
    26  
    27  	. "gopkg.in/check.v1"
    28  
    29  	"github.com/snapcore/snapd/dirs"
    30  	_ "github.com/snapcore/snapd/interfaces/builtin"
    31  	"github.com/snapcore/snapd/snap"
    32  	"github.com/snapcore/snapd/snap/snaptest"
    33  	"github.com/snapcore/snapd/testutil"
    34  	"github.com/snapcore/snapd/wrappers"
    35  )
    36  
    37  type dbusTestSuite struct {
    38  	tempdir string
    39  }
    40  
    41  var _ = Suite(&dbusTestSuite{})
    42  
    43  func (s *dbusTestSuite) SetUpTest(c *C) {
    44  	s.tempdir = c.MkDir()
    45  	dirs.SetRootDir(s.tempdir)
    46  }
    47  
    48  func (s *dbusTestSuite) TearDownTest(c *C) {
    49  	dirs.SetRootDir("")
    50  }
    51  
    52  const dbusSnapYaml = `
    53  name: snapname
    54  version: 1.0
    55  slots:
    56    system1:
    57      interface: dbus
    58      bus: system
    59      name: org.example.Foo
    60    system2:
    61      interface: dbus
    62      bus: system
    63      name: org.example.Bar
    64    session1:
    65      interface: dbus
    66      bus: session
    67      name: org.example.Foo
    68    session2:
    69      interface: dbus
    70      bus: session
    71      name: org.example.Bar
    72  apps:
    73    system-svc:
    74      command: bin/start-system
    75      daemon: simple
    76      activates-on:
    77        - system1
    78        - system2
    79    session-svc:
    80      command: bin/start-session
    81      daemon: simple
    82      daemon-scope: user
    83      activates-on:
    84        - session1
    85        - session2
    86  `
    87  
    88  func (s *dbusTestSuite) TestGenerateDBusActivationFile(c *C) {
    89  	info := snaptest.MockSnap(c, dbusSnapYaml, &snap.SideInfo{Revision: snap.R(12)})
    90  
    91  	app := info.Apps["system-svc"]
    92  	svcWrapper, err := wrappers.GenerateDBusActivationFile(app, "org.example.Foo")
    93  	c.Assert(err, IsNil)
    94  	c.Check(string(svcWrapper), Equals, `[D-BUS Service]
    95  Name=org.example.Foo
    96  Comment=Bus name for snap application snapname.system-svc
    97  SystemdService=snap.snapname.system-svc.service
    98  Exec=/usr/bin/snap run snapname.system-svc
    99  AssumedAppArmorLabel=snap.snapname.system-svc
   100  User=root
   101  X-Snap=snapname
   102  `)
   103  
   104  	app = info.Apps["session-svc"]
   105  	svcWrapper, err = wrappers.GenerateDBusActivationFile(app, "org.example.Foo")
   106  	c.Assert(err, IsNil)
   107  	c.Check(string(svcWrapper), Equals, `[D-BUS Service]
   108  Name=org.example.Foo
   109  Comment=Bus name for snap application snapname.session-svc
   110  SystemdService=snap.snapname.session-svc.service
   111  Exec=/usr/bin/snap run snapname.session-svc
   112  AssumedAppArmorLabel=snap.snapname.session-svc
   113  X-Snap=snapname
   114  `)
   115  }
   116  
   117  func (s *dbusTestSuite) TestAddSnapDBusActivationFiles(c *C) {
   118  	info := snaptest.MockSnap(c, dbusSnapYaml, &snap.SideInfo{Revision: snap.R(12)})
   119  
   120  	err := wrappers.AddSnapDBusActivationFiles(info)
   121  	c.Assert(err, IsNil)
   122  
   123  	c.Check(filepath.Join(dirs.SnapDBusSessionServicesDir, "org.example.Foo.service"), testutil.FileContains, "SystemdService=snap.snapname.session-svc.service\n")
   124  	c.Check(filepath.Join(dirs.SnapDBusSessionServicesDir, "org.example.Bar.service"), testutil.FileContains, "SystemdService=snap.snapname.session-svc.service\n")
   125  
   126  	c.Check(filepath.Join(dirs.SnapDBusSystemServicesDir, "org.example.Foo.service"), testutil.FileContains, "SystemdService=snap.snapname.system-svc.service\n")
   127  	c.Check(filepath.Join(dirs.SnapDBusSystemServicesDir, "org.example.Bar.service"), testutil.FileContains, "SystemdService=snap.snapname.system-svc.service\n")
   128  }
   129  
   130  func (s *dbusTestSuite) TestAddSnapDBusActivationFilesRemovesLeftovers(c *C) {
   131  	c.Assert(os.MkdirAll(dirs.SnapDBusSessionServicesDir, 0755), IsNil)
   132  	c.Assert(os.MkdirAll(dirs.SnapDBusSystemServicesDir, 0755), IsNil)
   133  
   134  	sessionSvc := filepath.Join(dirs.SnapDBusSessionServicesDir, "org.example.Baz.service")
   135  	c.Assert(ioutil.WriteFile(sessionSvc, []byte("[D-BUS Service]\nX-Snap=snapname\n"), 0644), IsNil)
   136  	systemSvc := filepath.Join(dirs.SnapDBusSessionServicesDir, "org.example.Baz.service")
   137  	c.Assert(ioutil.WriteFile(systemSvc, []byte("[D-BUS Service]\nX-Snap=snapname\n"), 0644), IsNil)
   138  
   139  	otherSessionSvc := filepath.Join(dirs.SnapDBusSessionServicesDir, "org.example.OtherSnap.service")
   140  	c.Assert(ioutil.WriteFile(otherSessionSvc, []byte("[D-BUS Service]\nX-Snap=other-snap\n"), 0644), IsNil)
   141  	otherSystemSvc := filepath.Join(dirs.SnapDBusSystemServicesDir, "org.example.OtherSnap.service")
   142  	c.Assert(ioutil.WriteFile(otherSystemSvc, []byte("[D-BUS Service]\nX-Snap=other-snap\n"), 0644), IsNil)
   143  
   144  	info := snaptest.MockSnap(c, dbusSnapYaml, &snap.SideInfo{Revision: snap.R(12)})
   145  	err := wrappers.AddSnapDBusActivationFiles(info)
   146  	c.Assert(err, IsNil)
   147  
   148  	c.Check(sessionSvc, testutil.FileAbsent)
   149  	c.Check(systemSvc, testutil.FileAbsent)
   150  
   151  	// Files belonging to other snap are left as is
   152  	c.Check(otherSessionSvc, testutil.FilePresent)
   153  	c.Check(otherSystemSvc, testutil.FilePresent)
   154  }
   155  
   156  func (s *dbusTestSuite) TestRemoveSnapDBusActivationFiles(c *C) {
   157  	c.Assert(os.MkdirAll(dirs.SnapDBusSessionServicesDir, 0755), IsNil)
   158  	c.Assert(os.MkdirAll(dirs.SnapDBusSystemServicesDir, 0755), IsNil)
   159  
   160  	sessionSvc := filepath.Join(dirs.SnapDBusSessionServicesDir, "org.example.Baz.service")
   161  	c.Assert(ioutil.WriteFile(sessionSvc, []byte("[D-BUS Service]\nX-Snap=snapname\n"), 0644), IsNil)
   162  	systemSvc := filepath.Join(dirs.SnapDBusSessionServicesDir, "org.example.Baz.service")
   163  	c.Assert(ioutil.WriteFile(systemSvc, []byte("[D-BUS Service]\nX-Snap=snapname\n"), 0644), IsNil)
   164  
   165  	otherSessionSvc := filepath.Join(dirs.SnapDBusSessionServicesDir, "org.example.OtherSnap.service")
   166  	c.Assert(ioutil.WriteFile(otherSessionSvc, []byte("[D-BUS Service]\nX-Snap=other-snap\n"), 0644), IsNil)
   167  	otherSystemSvc := filepath.Join(dirs.SnapDBusSystemServicesDir, "org.example.OtherSnap.service")
   168  	c.Assert(ioutil.WriteFile(otherSystemSvc, []byte("[D-BUS Service]\nX-Snap=other-snap\n"), 0644), IsNil)
   169  
   170  	info := snaptest.MockSnap(c, dbusSnapYaml, &snap.SideInfo{Revision: snap.R(12)})
   171  	err := wrappers.RemoveSnapDBusActivationFiles(info)
   172  	c.Assert(err, IsNil)
   173  
   174  	c.Check(sessionSvc, testutil.FileAbsent)
   175  	c.Check(systemSvc, testutil.FileAbsent)
   176  
   177  	// Files belonging to other snap are left as is
   178  	c.Check(otherSessionSvc, testutil.FilePresent)
   179  	c.Check(otherSystemSvc, testutil.FilePresent)
   180  }
   181  
   182  func (s *dbusTestSuite) TestAddSnapDBusActivationFilesInvalidData(c *C) {
   183  	info, err := snap.InfoFromSnapYaml([]byte(`
   184  name: snapname
   185  version: 1.0
   186  slots:
   187    invalid-name:
   188      interface: dbus
   189      bus: system
   190      name: 'invalid bus name'
   191    invalid-bus:
   192      interface: dbus
   193      bus: accessibility
   194      name: org.example.Foo
   195  apps:
   196    svc:
   197      command: bin/svc
   198      daemon: simple
   199      activates-on: [invalid-name, invalid-bus]
   200  `))
   201  	c.Assert(err, IsNil)
   202  	// The slots with invalid data have been removed
   203  	c.Check(info.Slots, HasLen, 0)
   204  	c.Check(info.BadInterfaces["invalid-name"], Equals, `invalid DBus bus name: "invalid bus name"`)
   205  	c.Check(info.BadInterfaces["invalid-bus"], Equals, `bus 'accessibility' must be one of 'session' or 'system'`)
   206  
   207  	// No activation files are written out for the invalid slots
   208  	err = wrappers.AddSnapDBusActivationFiles(info)
   209  	c.Assert(err, IsNil)
   210  	matches, err := filepath.Glob(filepath.Join(dirs.SnapDBusSessionServicesDir, "*.service"))
   211  	c.Check(err, IsNil)
   212  	c.Check(matches, HasLen, 0)
   213  	matches, err = filepath.Glob(filepath.Join(dirs.SnapDBusSystemServicesDir, "*.service"))
   214  	c.Check(err, IsNil)
   215  	c.Check(matches, HasLen, 0)
   216  }