gopkg.in/ubuntu-core/snappy.v0@v0.0.0-20210902073436-25a8614f10a6/wrappers/core18_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 wrappers_test
    21  
    22  import (
    23  	"fmt"
    24  	"os"
    25  	"path/filepath"
    26  	"syscall"
    27  
    28  	. "gopkg.in/check.v1"
    29  
    30  	"github.com/snapcore/snapd/dirs"
    31  	"github.com/snapcore/snapd/logger"
    32  	"github.com/snapcore/snapd/osutil"
    33  	"github.com/snapcore/snapd/progress"
    34  	"github.com/snapcore/snapd/release"
    35  	"github.com/snapcore/snapd/snap"
    36  	"github.com/snapcore/snapd/snap/snaptest"
    37  	"github.com/snapcore/snapd/systemd"
    38  	"github.com/snapcore/snapd/testutil"
    39  	"github.com/snapcore/snapd/wrappers"
    40  )
    41  
    42  func makeMockSnapdSnap(c *C) *snap.Info {
    43  	err := os.MkdirAll(dirs.SnapServicesDir, 0755)
    44  	c.Assert(err, IsNil)
    45  	err = os.MkdirAll(dirs.SnapUserServicesDir, 0755)
    46  	c.Assert(err, IsNil)
    47  	err = os.MkdirAll(dirs.SnapDBusSystemPolicyDir, 0755)
    48  	c.Assert(err, IsNil)
    49  	err = os.MkdirAll(dirs.SnapDBusSessionPolicyDir, 0755)
    50  	c.Assert(err, IsNil)
    51  
    52  	info := snaptest.MockSnapWithFiles(c, snapdYaml, &snap.SideInfo{Revision: snap.R(1)}, [][]string{
    53  		// system services
    54  		{"lib/systemd/system/snapd.service", "[Unit]\n[Service]\nExecStart=/usr/lib/snapd/snapd\n# X-Snapd-Snap: do-not-start"},
    55  		{"lib/systemd/system/snapd.system-shutdown.service", "[Unit]\n[Service]\nExecStart=/bin/umount --everything\n# X-Snapd-Snap: do-not-start"},
    56  		{"lib/systemd/system/snapd.autoimport.service", "[Unit]\n[Service]\nExecStart=/usr/bin/snap auto-import"},
    57  		{"lib/systemd/system/snapd.socket", "[Unit]\n[Socket]\nListenStream=/run/snapd.socket"},
    58  		{"lib/systemd/system/snapd.snap-repair.timer", "[Unit]\n[Timer]\nOnCalendar=*-*-* 5,11,17,23:00"},
    59  		// user services
    60  		{"usr/lib/systemd/user/snapd.session-agent.service", "[Unit]\n[Service]\nExecStart=/usr/bin/snap session-agent"},
    61  		{"usr/lib/systemd/user/snapd.session-agent.socket", "[Unit]\n[Socket]\nListenStream=%t/snap-session.socket"},
    62  		// D-Bus configuration
    63  		{"usr/share/dbus-1/session.d/snapd.session-services.conf", "<busconfig/>"},
    64  		{"usr/share/dbus-1/system.d/snapd.system-services.conf", "<busconfig/>"},
    65  		// Extra non-snapd D-Bus config that shouldn't be copied
    66  		{"usr/share/dbus-1/system.d/io.netplan.Netplan.conf", "<busconfig/>"},
    67  		// D-Bus activation files
    68  		{"usr/share/dbus-1/services/io.snapcraft.Launcher.service", "[D-BUS Service]\nName=io.snapcraft.Launcher"},
    69  		{"usr/share/dbus-1/services/io.snapcraft.Settings.service", "[D-BUS Service]\nName=io.snapcraft.Settings"},
    70  		{"usr/share/dbus-1/services/io.snapcraft.SessionAgent.service", "[D-BUS Service]\nName=io.snapcraft.SessionAgent"},
    71  	})
    72  
    73  	return info
    74  }
    75  
    76  type mockSystemctlError struct {
    77  	msg      string
    78  	exitCode int
    79  }
    80  
    81  func (m *mockSystemctlError) Msg() []byte {
    82  	return []byte(m.msg)
    83  }
    84  
    85  func (m *mockSystemctlError) ExitCode() int {
    86  	return m.exitCode
    87  }
    88  
    89  func (m *mockSystemctlError) Error() string {
    90  	return fmt.Sprintf("mocked systemctl error: code: %v msg: %q", m.exitCode, m.msg)
    91  }
    92  
    93  func (s *servicesTestSuite) TestAddSnapServicesForSnapdOnCore(c *C) {
    94  	restore := release.MockOnClassic(false)
    95  	defer restore()
    96  
    97  	restore = release.MockReleaseInfo(&release.OS{ID: "ubuntu"})
    98  	defer restore()
    99  
   100  	// reset root dir
   101  	dirs.SetRootDir(s.tempdir)
   102  
   103  	systemctlRestorer := systemd.MockSystemctl(func(cmd ...string) ([]byte, error) {
   104  		s.sysdLog = append(s.sysdLog, cmd)
   105  		if cmd[0] == "show" && cmd[1] == "--property=Id,ActiveState,UnitFileState,Type" {
   106  			s := fmt.Sprintf("Type=oneshot\nId=%s\nActiveState=inactive\nUnitFileState=enabled\n", cmd[2])
   107  			return []byte(s), nil
   108  		}
   109  		if len(cmd) == 2 && cmd[0] == "is-enabled" {
   110  			// pretend snapd.socket is disabled
   111  			if cmd[1] == "snapd.socket" {
   112  				return []byte("disabled"), &mockSystemctlError{msg: "disabled", exitCode: 1}
   113  			}
   114  			return []byte("enabled"), nil
   115  		}
   116  		return []byte("ActiveState=inactive\n"), nil
   117  	})
   118  	defer systemctlRestorer()
   119  
   120  	info := makeMockSnapdSnap(c)
   121  	// add the snapd service
   122  	err := wrappers.AddSnapdSnapServices(info, progress.Null)
   123  	c.Assert(err, IsNil)
   124  
   125  	mountUnit := fmt.Sprintf(`[Unit]
   126  Description=Make the snapd snap tooling available for the system
   127  Before=snapd.service
   128  
   129  [Mount]
   130  What=%s/snap/snapd/1/usr/lib/snapd
   131  Where=/usr/lib/snapd
   132  Type=none
   133  Options=bind
   134  
   135  [Install]
   136  WantedBy=snapd.service
   137  `, dirs.GlobalRootDir)
   138  	for _, entry := range [][]string{{
   139  		// check that snapd.service is created
   140  		filepath.Join(dirs.SnapServicesDir, "snapd.service"),
   141  		// and paths get re-written
   142  		fmt.Sprintf("[Unit]\n[Service]\nExecStart=%[1]s/snapd/1/usr/lib/snapd/snapd\n# X-Snapd-Snap: do-not-start\n[Unit]\nRequiresMountsFor=%[1]s/snapd/1\n", dirs.SnapMountDir),
   143  	}, {
   144  		// check that snapd.autoimport.service is created
   145  		filepath.Join(dirs.SnapServicesDir, "snapd.autoimport.service"),
   146  		// and paths get re-written
   147  		fmt.Sprintf("[Unit]\n[Service]\nExecStart=%[1]s/snapd/1/usr/bin/snap auto-import\n[Unit]\nRequiresMountsFor=%[1]s/snapd/1\n", dirs.SnapMountDir),
   148  	}, {
   149  		// check that snapd.system-shutdown.service is created
   150  		filepath.Join(dirs.SnapServicesDir, "snapd.system-shutdown.service"),
   151  		// and paths *do not* get re-written
   152  		"[Unit]\n[Service]\nExecStart=/bin/umount --everything\n# X-Snapd-Snap: do-not-start",
   153  	}, {
   154  		// check that usr-lib-snapd.mount is created
   155  		filepath.Join(dirs.SnapServicesDir, "usr-lib-snapd.mount"),
   156  		mountUnit,
   157  	}, {
   158  		// check that snapd.session-agent.service is created
   159  		filepath.Join(dirs.SnapUserServicesDir, "snapd.session-agent.service"),
   160  		// and paths get re-written
   161  		fmt.Sprintf("[Unit]\n[Service]\nExecStart=%[1]s/snapd/1/usr/bin/snap session-agent\n[Unit]\nRequiresMountsFor=%[1]s/snapd/1\n", dirs.SnapMountDir),
   162  	}, {
   163  		// check that snapd.session-agent.socket is created
   164  		filepath.Join(dirs.SnapUserServicesDir, "snapd.session-agent.socket"),
   165  		"[Unit]\n[Socket]\nListenStream=%t/snap-session.socket",
   166  	}, {
   167  		filepath.Join(dirs.SnapDBusSystemPolicyDir, "snapd.system-services.conf"),
   168  		"<busconfig/>",
   169  	}, {
   170  		filepath.Join(dirs.SnapDBusSessionPolicyDir, "snapd.session-services.conf"),
   171  		"<busconfig/>",
   172  	}, {
   173  		filepath.Join(dirs.SnapDBusSessionServicesDir, "io.snapcraft.Launcher.service"),
   174  		"[D-BUS Service]\nName=io.snapcraft.Launcher",
   175  	}, {
   176  		filepath.Join(dirs.SnapDBusSessionServicesDir, "io.snapcraft.Settings.service"),
   177  		"[D-BUS Service]\nName=io.snapcraft.Settings",
   178  	}, {
   179  		filepath.Join(dirs.SnapDBusSessionServicesDir, "io.snapcraft.SessionAgent.service"),
   180  		"[D-BUS Service]\nName=io.snapcraft.SessionAgent",
   181  	}} {
   182  		c.Check(entry[0], testutil.FileEquals, entry[1])
   183  	}
   184  
   185  	// Non-snapd D-Bus config is not copied
   186  	c.Check(filepath.Join(dirs.SnapDBusSystemPolicyDir, "io.netplan.Netplan.conf"), testutil.FileAbsent)
   187  
   188  	// check the systemctl calls
   189  	c.Check(s.sysdLog, DeepEquals, [][]string{
   190  		{"daemon-reload"},
   191  		{"enable", "usr-lib-snapd.mount"},
   192  		{"stop", "usr-lib-snapd.mount"},
   193  		{"show", "--property=ActiveState", "usr-lib-snapd.mount"},
   194  		{"start", "usr-lib-snapd.mount"},
   195  		{"daemon-reload"},
   196  		{"is-enabled", "snapd.autoimport.service"},
   197  		{"is-enabled", "snapd.service"},
   198  		{"is-enabled", "snapd.snap-repair.timer"},
   199  		// test pretends snapd.socket is disabled and needs enabling
   200  		{"is-enabled", "snapd.socket"},
   201  		{"enable", "snapd.socket"},
   202  		{"is-enabled", "snapd.system-shutdown.service"},
   203  		{"is-active", "snapd.autoimport.service"},
   204  		{"stop", "snapd.autoimport.service"},
   205  		{"show", "--property=ActiveState", "snapd.autoimport.service"},
   206  		{"start", "snapd.autoimport.service"},
   207  		{"is-active", "snapd.snap-repair.timer"},
   208  		{"stop", "snapd.snap-repair.timer"},
   209  		{"show", "--property=ActiveState", "snapd.snap-repair.timer"},
   210  		{"start", "snapd.snap-repair.timer"},
   211  		{"is-active", "snapd.socket"},
   212  		{"start", "snapd.service"},
   213  		{"start", "--no-block", "snapd.seeded.service"},
   214  		{"start", "--no-block", "snapd.autoimport.service"},
   215  		{"--user", "--global", "disable", "snapd.session-agent.service"},
   216  		{"--user", "--global", "enable", "snapd.session-agent.service"},
   217  		{"--user", "--global", "disable", "snapd.session-agent.socket"},
   218  		{"--user", "--global", "enable", "snapd.session-agent.socket"},
   219  	})
   220  }
   221  
   222  func (s *servicesTestSuite) TestAddSnapServicesForSnapdOnClassic(c *C) {
   223  	restore := release.MockOnClassic(true)
   224  	defer restore()
   225  
   226  	info := makeMockSnapdSnap(c)
   227  	// add the snapd service
   228  	err := wrappers.AddSnapdSnapServices(info, progress.Null)
   229  	c.Assert(err, IsNil)
   230  
   231  	// check that snapd services were *not* created
   232  	c.Check(osutil.FileExists(filepath.Join(dirs.SnapServicesDir, "snapd.service")), Equals, false)
   233  	c.Check(osutil.FileExists(filepath.Join(dirs.SnapServicesDir, "snapd.autoimport.service")), Equals, false)
   234  	c.Check(osutil.FileExists(filepath.Join(dirs.SnapServicesDir, "snapd.system-shutdown.service")), Equals, false)
   235  	c.Check(osutil.FileExists(filepath.Join(dirs.SnapServicesDir, "usr-lib-snapd.mount")), Equals, false)
   236  	c.Check(osutil.FileExists(filepath.Join(dirs.SnapUserServicesDir, "snapd.session-agent.service")), Equals, false)
   237  	c.Check(osutil.FileExists(filepath.Join(dirs.SnapUserServicesDir, "snapd.session-agent.socket")), Equals, false)
   238  	c.Check(osutil.FileExists(filepath.Join(dirs.SnapDBusSystemPolicyDir, "snapd.system-services.conf")), Equals, false)
   239  	c.Check(osutil.FileExists(filepath.Join(dirs.SnapDBusSessionPolicyDir, "snapd.session-services.conf")), Equals, false)
   240  	c.Check(osutil.FileExists(filepath.Join(dirs.SnapDBusSessionServicesDir, "io.snapcraft.Launcher.service")), Equals, false)
   241  	c.Check(osutil.FileExists(filepath.Join(dirs.SnapDBusSessionServicesDir, "io.snapcraft.Settings.service")), Equals, false)
   242  	c.Check(osutil.FileExists(filepath.Join(dirs.SnapDBusSessionServicesDir, "io.snapcraft.SessionAgent.service")), Equals, false)
   243  
   244  	// check that no systemctl calls happened
   245  	c.Check(s.sysdLog, IsNil)
   246  }
   247  
   248  func (s *servicesTestSuite) TestAddSessionServicesWithReadOnlyFilesystem(c *C) {
   249  	restore := release.MockOnClassic(false)
   250  	defer restore()
   251  
   252  	restoreEnsureDirState := wrappers.MockEnsureDirState(func(dir string, glob string, content map[string]osutil.FileState) (changed, removed []string, err error) {
   253  		return nil, nil, &os.PathError{Err: syscall.EROFS}
   254  	})
   255  	defer restoreEnsureDirState()
   256  
   257  	info := makeMockSnapdSnap(c)
   258  
   259  	logBuf, restore := logger.MockLogger()
   260  	defer restore()
   261  
   262  	// add the snapd service
   263  	err := wrappers.AddSnapdSnapServices(info, progress.Null)
   264  
   265  	// didn't fail despite of read-only SnapDBusSessionPolicyDir
   266  	c.Assert(err, IsNil)
   267  
   268  	// check that snapd services were *not* created
   269  	c.Check(osutil.FileExists(filepath.Join(dirs.SnapServicesDir, "snapd.service")), Equals, true)
   270  	c.Check(osutil.FileExists(filepath.Join(dirs.SnapServicesDir, "snapd.autoimport.service")), Equals, true)
   271  	c.Check(osutil.FileExists(filepath.Join(dirs.SnapServicesDir, "snapd.system-shutdown.service")), Equals, true)
   272  	c.Check(osutil.FileExists(filepath.Join(dirs.SnapServicesDir, "usr-lib-snapd.mount")), Equals, true)
   273  	c.Check(osutil.FileExists(filepath.Join(dirs.SnapUserServicesDir, "snapd.session-agent.service")), Equals, true)
   274  	c.Check(osutil.FileExists(filepath.Join(dirs.SnapUserServicesDir, "snapd.session-agent.socket")), Equals, true)
   275  	c.Check(osutil.FileExists(filepath.Join(dirs.SnapDBusSystemPolicyDir, "snapd.system-services.conf")), Equals, true)
   276  	c.Check(osutil.FileExists(filepath.Join(dirs.SnapDBusSessionPolicyDir, "snapd.session-services.conf")), Equals, false)
   277  
   278  	c.Assert(logBuf.String(), testutil.Contains, "/etc/dbus-1/session.d appears to be read-only, could not write snapd dbus config files")
   279  }
   280  
   281  func (s *servicesTestSuite) TestAddSnapdServicesWithNonSnapd(c *C) {
   282  	restore := release.MockOnClassic(false)
   283  	defer restore()
   284  
   285  	info := snaptest.MockInfo(c, "name: foo\nversion: 1.0", &snap.SideInfo{})
   286  	restore = release.MockReleaseInfo(&release.OS{ID: "ubuntu"})
   287  	defer restore()
   288  
   289  	err := wrappers.AddSnapdSnapServices(info, progress.Null)
   290  	c.Assert(err, ErrorMatches, `internal error: adding explicit snapd services for snap "foo" type "app" is unexpected`)
   291  }
   292  
   293  func (s *servicesTestSuite) TestRemoveSnapServicesForFirstInstallSnapdOnCore(c *C) {
   294  	restore := release.MockOnClassic(false)
   295  	defer restore()
   296  
   297  	restore = release.MockReleaseInfo(&release.OS{ID: "ubuntu"})
   298  	defer restore()
   299  
   300  	// reset root dir
   301  	dirs.SetRootDir(s.tempdir)
   302  
   303  	systemctlRestorer := systemd.MockSystemctl(func(cmd ...string) ([]byte, error) {
   304  		s.sysdLog = append(s.sysdLog, cmd)
   305  		if cmd[0] == "show" && cmd[1] == "--property=Id,ActiveState,UnitFileState,Type" {
   306  			s := fmt.Sprintf("Type=oneshot\nId=%s\nActiveState=inactive\nUnitFileState=enabled\n", cmd[2])
   307  			return []byte(s), nil
   308  		}
   309  		if len(cmd) == 4 && cmd[2] == "is-enabled" {
   310  			// pretend snapd.socket is disabled
   311  			if cmd[3] == "snapd.socket" {
   312  				return []byte("disabled"), &mockSystemctlError{msg: "disabled", exitCode: 1}
   313  			}
   314  			return []byte("enabled"), nil
   315  		}
   316  		return []byte("ActiveState=inactive\n"), nil
   317  	})
   318  	defer systemctlRestorer()
   319  
   320  	info := makeMockSnapdSnap(c)
   321  
   322  	units := [][]string{
   323  		{filepath.Join(dirs.SnapServicesDir, "usr-lib-snapd.mount"), "from-snapd"},
   324  		{filepath.Join(dirs.SnapServicesDir, "snapd.service"), "from-snapd"},
   325  		{filepath.Join(dirs.SnapServicesDir, "snapd.socket"), "from-snapd"},
   326  		{filepath.Join(dirs.SnapServicesDir, "snapd.snap-repair.timer"), "from-snapd"},
   327  		{filepath.Join(dirs.SnapServicesDir, "snapd.autoimport.service"), "from-snapd"},
   328  		{filepath.Join(dirs.SnapServicesDir, "snapd.system-shutdown.service"), "from-snapd"},
   329  		{filepath.Join(dirs.SnapUserServicesDir, "snapd.session-agent.service"), "from-snapd"},
   330  		{filepath.Join(dirs.SnapUserServicesDir, "snapd.session-agent.socket"), "from-snapd"},
   331  		{filepath.Join(dirs.SnapDBusSystemPolicyDir, "snapd.system-services.conf"), "from-snapd"},
   332  		{filepath.Join(dirs.SnapDBusSessionPolicyDir, "snapd.session-services.conf"), "from-snapd"},
   333  		// extra unit not present in core snap
   334  		{filepath.Join(dirs.SnapServicesDir, "snapd.not-in-core.service"), "from-snapd"},
   335  		// D-Bus service activation files
   336  		{filepath.Join(dirs.SnapDBusSessionServicesDir, "io.snapcraft.Launcher.service"), "from-snapd"},
   337  		{filepath.Join(dirs.SnapDBusSessionServicesDir, "io.snapcraft.Settings.service"), "from-snapd"},
   338  		{filepath.Join(dirs.SnapDBusSessionServicesDir, "io.snapcraft.SessionAgent.service"), "from-snapd"},
   339  	}
   340  	// content list uses absolute paths already
   341  	snaptest.PopulateDir("/", units)
   342  
   343  	// add the extra unit to the snap
   344  	snaptest.PopulateDir("/", [][]string{
   345  		{filepath.Join(info.MountDir(), "lib/systemd/system/snapd.not-in-core.service"), "from-snapd"},
   346  	})
   347  
   348  	coreUnits := [][]string{
   349  		{filepath.Join(dirs.GlobalRootDir, "lib/systemd/system/snapd.service"), "# X-Snapd-Snap: do-not-start"},
   350  		{filepath.Join(dirs.GlobalRootDir, "lib/systemd/system/snapd.socket"), "from-core"},
   351  		{filepath.Join(dirs.GlobalRootDir, "lib/systemd/system/snapd.snap-repair.timer"), "from-core"},
   352  		{filepath.Join(dirs.GlobalRootDir, "lib/systemd/system/snapd.autoimport.service"), "from-core"},
   353  		{filepath.Join(dirs.GlobalRootDir, "lib/systemd/system/snapd.system-shutdown.service"), "# X-Snapd-Snap: do-not-start"},
   354  		{filepath.Join(dirs.GlobalRootDir, "usr/lib/systemd/user/snapd.session-agent.service"), "from-core"},
   355  		{filepath.Join(dirs.GlobalRootDir, "usr/lib/systemd/user/snapd.session-agent.socket"), "from-core"},
   356  	}
   357  	// content list uses absolute paths already
   358  	snaptest.PopulateDir("/", coreUnits)
   359  
   360  	// remove the snapd service
   361  	err := wrappers.RemoveSnapdSnapServicesOnCore(info, progress.Null)
   362  	c.Assert(err, IsNil)
   363  
   364  	for _, unit := range units {
   365  		c.Check(unit[0], testutil.FileAbsent)
   366  	}
   367  
   368  	// check the systemctl calls
   369  	c.Check(s.sysdLog, DeepEquals, [][]string{
   370  		// pretend snapd socket needs enabling
   371  		{"--root", dirs.GlobalRootDir, "is-enabled", "snapd.socket"},
   372  		{"--root", dirs.GlobalRootDir, "enable", "snapd.socket"},
   373  
   374  		{"--root", dirs.GlobalRootDir, "is-enabled", "snapd.autoimport.service"},
   375  		{"--root", dirs.GlobalRootDir, "is-active", "snapd.autoimport.service"},
   376  		{"stop", "snapd.autoimport.service"},
   377  		{"show", "--property=ActiveState", "snapd.autoimport.service"},
   378  		{"start", "snapd.autoimport.service"},
   379  		{"--root", dirs.GlobalRootDir, "disable", "snapd.not-in-core.service"},
   380  		{"stop", "snapd.not-in-core.service"},
   381  		{"show", "--property=ActiveState", "snapd.not-in-core.service"},
   382  		{"--root", dirs.GlobalRootDir, "is-enabled", "snapd.service"},
   383  		{"--root", dirs.GlobalRootDir, "is-enabled", "snapd.system-shutdown.service"},
   384  		{"--root", dirs.GlobalRootDir, "is-enabled", "snapd.snap-repair.timer"},
   385  		{"--root", dirs.GlobalRootDir, "is-active", "snapd.snap-repair.timer"},
   386  		{"stop", "snapd.snap-repair.timer"},
   387  		{"show", "--property=ActiveState", "snapd.snap-repair.timer"},
   388  		{"start", "snapd.snap-repair.timer"},
   389  		{"--user", "--global", "--root", dirs.GlobalRootDir, "disable", "snapd.session-agent.service"},
   390  		{"--user", "--global", "--root", dirs.GlobalRootDir, "enable", "snapd.session-agent.service"},
   391  		{"--user", "--global", "--root", dirs.GlobalRootDir, "disable", "snapd.session-agent.socket"},
   392  		{"--user", "--global", "--root", dirs.GlobalRootDir, "enable", "snapd.session-agent.socket"},
   393  		{"--root", dirs.GlobalRootDir, "disable", "usr-lib-snapd.mount"},
   394  		{"stop", "usr-lib-snapd.mount"},
   395  		{"show", "--property=ActiveState", "usr-lib-snapd.mount"},
   396  	})
   397  }
   398  
   399  func (s *servicesTestSuite) TestRemoveSnapdServicesWithNonSnapd(c *C) {
   400  	restore := release.MockOnClassic(false)
   401  	defer restore()
   402  
   403  	info := snaptest.MockInfo(c, "name: foo\nversion: 1.0", &snap.SideInfo{})
   404  	restore = release.MockReleaseInfo(&release.OS{ID: "ubuntu"})
   405  	defer restore()
   406  
   407  	err := wrappers.RemoveSnapdSnapServicesOnCore(info, progress.Null)
   408  	c.Assert(err, ErrorMatches, `internal error: removing explicit snapd services for snap "foo" type "app" is unexpected`)
   409  }
   410  
   411  func (s *servicesTestSuite) TestDeriveSnapdDBusConfig(c *C) {
   412  	info := makeMockSnapdSnap(c)
   413  
   414  	sessionContent, systemContent, err := wrappers.DeriveSnapdDBusConfig(info)
   415  	c.Assert(err, IsNil)
   416  	c.Check(sessionContent, DeepEquals, map[string]osutil.FileState{
   417  		"snapd.session-services.conf": &osutil.FileReference{
   418  			Path: filepath.Join(info.MountDir(), "usr/share/dbus-1/session.d/snapd.session-services.conf"),
   419  		},
   420  	})
   421  	c.Check(systemContent, DeepEquals, map[string]osutil.FileState{
   422  		"snapd.system-services.conf": &osutil.FileReference{
   423  			Path: filepath.Join(info.MountDir(), "usr/share/dbus-1/system.d/snapd.system-services.conf"),
   424  		},
   425  	})
   426  }