func (s *FirstBootTestSuite) SetUpTest(c *C) { tempdir := c.MkDir() dirs.SetRootDir(tempdir) // mock the world! err := os.MkdirAll(filepath.Join(dirs.SnapSeedDir, "snaps"), 0755) c.Assert(err, IsNil) err = os.MkdirAll(filepath.Join(dirs.SnapSeedDir, "assertions"), 0755) c.Assert(err, IsNil) err = os.MkdirAll(dirs.SnapServicesDir, 0755) c.Assert(err, IsNil) os.Setenv("SNAPPY_SQUASHFS_UNPACK_FOR_TESTS", "1") s.systemctl = testutil.MockCommand(c, "systemctl", "") s.mockUdevAdm = testutil.MockCommand(c, "udevadm", "") err = ioutil.WriteFile(filepath.Join(dirs.SnapSeedDir, "seed.yaml"), nil, 0644) c.Assert(err, IsNil) rootPrivKey, _ := assertstest.GenerateKey(1024) storePrivKey, _ := assertstest.GenerateKey(752) s.storeSigning = assertstest.NewStoreStack("can0nical", rootPrivKey, storePrivKey) s.restore = sysdb.InjectTrusted(s.storeSigning.Trusted) s.brandPrivKey, _ = assertstest.GenerateKey(752) s.brandSigning = assertstest.NewSigningDB("my-brand", s.brandPrivKey) ovld, err := overlord.New() c.Assert(err, IsNil) s.overlord = ovld }
func (ms *mgrsSuite) SetUpTest(c *C) { ms.tempdir = c.MkDir() dirs.SetRootDir(ms.tempdir) err := os.MkdirAll(filepath.Dir(dirs.SnapStateFile), 0755) c.Assert(err, IsNil) os.Setenv("SNAPPY_SQUASHFS_UNPACK_FOR_TESTS", "1") // create a fake systemd environment os.MkdirAll(filepath.Join(dirs.SnapServicesDir, "multi-user.target.wants"), 0755) ms.prevctlCmd = systemd.SystemctlCmd systemd.SystemctlCmd = func(cmd ...string) ([]byte, error) { return []byte("ActiveState=inactive\n"), nil } ms.aa = testutil.MockCommand(c, "apparmor_parser", "") ms.udev = testutil.MockCommand(c, "udevadm", "") ms.umount = testutil.MockCommand(c, "umount", "") ms.snapDiscardNs = testutil.MockCommand(c, "snap-discard-ns", "") dirs.LibExecDir = ms.snapDiscardNs.BinDir() ms.storeSigning = assertstest.NewStoreStack("can0nical", rootPrivKey, storePrivKey) ms.restoreTrusted = sysdb.InjectTrusted(ms.storeSigning.Trusted) ms.devAcct = assertstest.NewAccount(ms.storeSigning, "devdevev", map[string]interface{}{ "account-id": "devdevdev", }, "") err = ms.storeSigning.Add(ms.devAcct) c.Assert(err, IsNil) o, err := overlord.New() c.Assert(err, IsNil) ms.o = o }
func (s *hookManagerSuite) TestHookTaskCorrectlyIncludesContext(c *C) { // Register a handler generator for the "test-hook" hook mockHandler := hooktest.NewMockHandler() mockHandlerGenerator := func(context *hookstate.Context) hookstate.Handler { return mockHandler } // Force the snap command to exit with a failure and print to stderr so we // can catch and verify it. s.command = testutil.MockCommand( c, "snap", ">&2 echo \"SNAP_CONTEXT=$SNAP_CONTEXT\"; exit 1") s.manager.Register(regexp.MustCompile("test-hook"), mockHandlerGenerator) s.manager.Ensure() s.manager.Wait() s.state.Lock() defer s.state.Unlock() c.Check(mockHandler.BeforeCalled, Equals, true) c.Check(mockHandler.DoneCalled, Equals, false) c.Check(mockHandler.ErrorCalled, Equals, true) c.Check(s.task.Kind(), Equals, "run-hook") c.Check(s.task.Status(), Equals, state.ErrorStatus) c.Check(s.change.Status(), Equals, state.ErrorStatus) checkTaskLogContains(c, s.task, regexp.MustCompile(".*SNAP_CONTEXT=\\S+")) }
func (s *hookManagerSuite) TestHookTaskCanKillHook(c *C) { // Force the snap command to hang s.command = testutil.MockCommand(c, "snap", "while true; do sleep 1; done") s.manager.Ensure() completed := make(chan struct{}) go func() { s.manager.Wait() close(completed) }() // Abort the change, which should kill the hanging hook, and wait for the // task to complete. s.state.Lock() s.change.Abort() s.state.Unlock() s.manager.Ensure() <-completed s.state.Lock() defer s.state.Unlock() c.Check(s.mockHandler.BeforeCalled, Equals, true) c.Check(s.mockHandler.DoneCalled, Equals, false) c.Check(s.mockHandler.ErrorCalled, Equals, true) c.Check(s.mockHandler.Err, ErrorMatches, ".*hook \"configure\" aborted.*") c.Check(s.task.Kind(), Equals, "run-hook") c.Check(s.task.Status(), Equals, state.ErrorStatus) c.Check(s.change.Status(), Equals, state.ErrorStatus) checkTaskLogContains(c, s.task, `.*hook "configure" aborted.*`) }
func (s *createUserSuite) SetUpTest(c *check.C) { s.mockHome = c.MkDir() s.restorer = osutil.MockUserLookup(func(string) (*user.User, error) { current, err := user.Current() if err != nil { c.Fatalf("user.Current() failed with %s", err) } return &user.User{ HomeDir: s.mockHome, Gid: current.Gid, Uid: current.Uid, }, nil }) s.mockAddUser = testutil.MockCommand(c, "adduser", "") s.mockUserMod = testutil.MockCommand(c, "usermod", "") }
func (s *hookManagerSuite) TestHookTaskHandlerErrorError(c *C) { // Register a handler generator for the "test-hook" hook mockHandler := hooktest.NewMockHandler() mockHandler.ErrorError = true mockHandlerGenerator := func(context *hookstate.Context) hookstate.Handler { return mockHandler } // Force the snap command to simply exit 1, so the handler Error() runs s.command = testutil.MockCommand(c, "snap", "exit 1") s.manager.Register(regexp.MustCompile("test-hook"), mockHandlerGenerator) s.manager.Ensure() s.manager.Wait() s.state.Lock() defer s.state.Unlock() c.Check(mockHandler.BeforeCalled, Equals, true) c.Check(mockHandler.DoneCalled, Equals, false) c.Check(mockHandler.ErrorCalled, Equals, true) c.Check(s.task.Kind(), Equals, "run-hook") c.Check(s.task.Status(), Equals, state.ErrorStatus) c.Check(s.change.Status(), Equals, state.ErrorStatus) checkTaskLogContains(c, s.task, regexp.MustCompile(".*Error failed at user request.*")) }
func (s *appArmorSuite) TestUnloadProfileReportsErrors(c *C) { cmd := testutil.MockCommand(c, "apparmor_parser", "exit 42") defer cmd.Restore() err := apparmor.UnloadProfile("snap.samba.smbd") c.Assert(err.Error(), Equals, `cannot unload apparmor profile: exit status 42 apparmor_parser output: `) }
func (s *appArmorSuite) TestLoadProfileRunsAppArmorParserReplace(c *C) { cmd := testutil.MockCommand(c, "apparmor_parser", "") defer cmd.Restore() err := apparmor.LoadProfile("/path/to/snap.samba.smbd") c.Assert(err, IsNil) c.Assert(cmd.Calls(), DeepEquals, [][]string{ {"apparmor_parser", "--replace", "--write-cache", "-O", "no-expr-simplify", "--cache-loc=/var/cache/apparmor", "/path/to/snap.samba.smbd"}, }) }
func (s *appArmorSuite) TestUnloadProfileRunsAppArmorParserRemove(c *C) { cmd := testutil.MockCommand(c, "apparmor_parser", "") defer cmd.Restore() err := apparmor.UnloadProfile("snap.samba.smbd") c.Assert(err, IsNil) c.Assert(cmd.Calls(), DeepEquals, [][]string{ {"apparmor_parser", "--remove", "snap.samba.smbd"}, }) }
func (s *uDevSuite) TestReloadUDevRulesRunsUDevAdm(c *C) { cmd := testutil.MockCommand(c, "udevadm", "") defer cmd.Restore() err := udev.ReloadRules() c.Assert(err, IsNil) c.Assert(cmd.Calls(), DeepEquals, [][]string{ {"udevadm", "control", "--reload-rules"}, {"udevadm", "trigger"}, }) }
func (s *appArmorSuite) TestLoadProfileReportsErrors(c *C) { cmd := testutil.MockCommand(c, "apparmor_parser", "exit 42") defer cmd.Restore() err := apparmor.LoadProfile("/path/to/snap.samba.smbd") c.Assert(err.Error(), Equals, `cannot load apparmor profile: exit status 42 apparmor_parser output: `) c.Assert(cmd.Calls(), DeepEquals, [][]string{ {"apparmor_parser", "--replace", "--write-cache", "-O", "no-expr-simplify", "--cache-loc=/var/cache/apparmor", "/path/to/snap.samba.smbd"}, }) }
func (s *SystemdTestSuite) TestFuseInContainer(c *C) { if !osutil.FileExists("/dev/fuse") { c.Skip("No /dev/fuse on the system") } systemdCmd := testutil.MockCommand(c, "systemd-detect-virt", ` echo lxc exit 0 `) defer systemdCmd.Restore() fuseCmd := testutil.MockCommand(c, "squashfuse", ` exit 0 `) defer fuseCmd.Restore() mockSnapPath := filepath.Join(c.MkDir(), "/var/lib/snappy/snaps/foo_1.0.snap") err := os.MkdirAll(filepath.Dir(mockSnapPath), 0755) c.Assert(err, IsNil) err = ioutil.WriteFile(mockSnapPath, nil, 0644) c.Assert(err, IsNil) mountUnitName, err := New("", nil).WriteMountUnitFile("foo", mockSnapPath, "/apps/foo/1.0", "squashfs") c.Assert(err, IsNil) defer os.Remove(mountUnitName) mount, err := ioutil.ReadFile(filepath.Join(dirs.SnapServicesDir, mountUnitName)) c.Assert(err, IsNil) c.Assert(string(mount), Equals, fmt.Sprintf(`[Unit] Description=Mount unit for foo [Mount] What=%s Where=/apps/foo/1.0 Type=fuse.squashfuse Options=ro,allow_other [Install] WantedBy=multi-user.target `, mockSnapPath)) }
func (s *setupSuite) SetUpTest(c *C) { dirs.SetRootDir(c.MkDir()) err := os.MkdirAll(filepath.Join(dirs.GlobalRootDir, "etc", "systemd", "system", "multi-user.target.wants"), 0755) c.Assert(err, IsNil) s.prevctlCmd = systemd.SystemctlCmd systemd.SystemctlCmd = func(cmd ...string) ([]byte, error) { return []byte("ActiveState=inactive\n"), nil } s.umount = testutil.MockCommand(c, "umount", "") }
func (s *backendSuite) SetUpTest(c *C) { s.Backend = &udev.Backend{} s.BackendSuite.SetUpTest(c) // Mock away any real udev interaction s.udevadmCmd = testutil.MockCommand(c, "udevadm", "") // Prepare a directory for udev rules // NOTE: Normally this is a part of the OS snap. err := os.MkdirAll(dirs.SnapUdevRulesDir, 0700) c.Assert(err, IsNil) }
func (s *nsSuite) TestDiscardNamespaceMntFileAbsent(c *C) { // Mock the snap-discard-ns command cmd := testutil.MockCommand(c, "snap-discard-ns", "") dirs.LibExecDir = cmd.BinDir() defer cmd.Restore() // don't create the .mnt file that triggers the discard operation // ask the backend to discard the namespace err := s.be.DiscardSnapNamespace("snap-name") c.Assert(err, IsNil) c.Check(cmd.Calls(), IsNil) }
func (s *backendSuite) SetUpTest(c *C) { s.Backend = &apparmor.Backend{} s.BackendSuite.SetUpTest(c) // Prepare a directory for apparmor profiles. // NOTE: Normally this is a part of the OS snap. err := os.MkdirAll(dirs.SnapAppArmorDir, 0700) c.Assert(err, IsNil) err = os.MkdirAll(dirs.AppArmorCacheDir, 0700) c.Assert(err, IsNil) // Mock away any real apparmor interaction s.parserCmd = testutil.MockCommand(c, "apparmor_parser", fakeAppArmorParser) }
func (s *nsSuite) TestDiscardNamespaceMntFilePresent(c *C) { // Mock the snap-discard-ns command cmd := testutil.MockCommand(c, "snap-discard-ns", "") dirs.LibExecDir = cmd.BinDir() defer cmd.Restore() // the presence of the .mnt file is the trigger so create it now c.Assert(os.MkdirAll(dirs.SnapRunNsDir, 0755), IsNil) c.Assert(ioutil.WriteFile(filepath.Join(dirs.SnapRunNsDir, "snap-name.mnt"), nil, 0644), IsNil) err := s.be.DiscardSnapNamespace("snap-name") c.Assert(err, IsNil) c.Check(cmd.Calls(), DeepEquals, [][]string{{"snap-discard-ns", "snap-name"}}) }
func (s *kmodSuite) TestModprobeCall(c *C) { cmd := testutil.MockCommand(c, "modprobe", "") defer cmd.Restore() err := kmod.LoadModules([]string{ "module1", "module2", }) c.Assert(err, IsNil) c.Assert(cmd.Calls(), DeepEquals, [][]string{ {"modprobe", "--syslog", "module1"}, {"modprobe", "--syslog", "module2"}, }) }
func (s *nsSuite) TestDiscardNamespaceSilentFailure(c *C) { // Mock the snap-discard-ns command, make it fail cmd := testutil.MockCommand(c, "snap-discard-ns", "exit 1") dirs.LibExecDir = cmd.BinDir() defer cmd.Restore() // the presence of the .mnt file is the trigger so create it now c.Assert(os.MkdirAll(dirs.SnapRunNsDir, 0755), IsNil) c.Assert(ioutil.WriteFile(filepath.Join(dirs.SnapRunNsDir, "snap-name.mnt"), nil, 0644), IsNil) // ask the backend to discard the namespace err := s.be.DiscardSnapNamespace("snap-name") c.Assert(err, ErrorMatches, `cannot discard preserved namespaces of snap "snap-name": exit status 1`) c.Check(cmd.Calls(), DeepEquals, [][]string{{"snap-discard-ns", "snap-name"}}) }
func (s *appArmorSuite) TestUnloadRemovesCachedProfile(c *C) { cmd := testutil.MockCommand(c, "apparmor_parser", "") defer cmd.Restore() dirs.SetRootDir(c.MkDir()) defer dirs.SetRootDir("") err := os.MkdirAll(dirs.AppArmorCacheDir, 0755) c.Assert(err, IsNil) fname := filepath.Join(dirs.AppArmorCacheDir, "profile") ioutil.WriteFile(fname, []byte("blob"), 0600) err = apparmor.UnloadProfile("profile") c.Assert(err, IsNil) _, err = os.Stat(fname) c.Check(os.IsNotExist(err), Equals, true) }
func (s *hookManagerSuite) SetUpTest(c *C) { dirs.SetRootDir(c.MkDir()) s.state = state.New(nil) manager, err := hookstate.Manager(s.state) c.Assert(err, IsNil) s.manager = manager s.state.Lock() s.task = hookstate.HookTask(s.state, "test summary", "test-snap", snap.R(1), "test-hook") c.Assert(s.task, NotNil, Commentf("Expected HookTask to return a task")) s.change = s.state.NewChange("kind", "summary") s.change.AddTask(s.task) s.state.Unlock() s.command = testutil.MockCommand(c, "snap", "") }
func (s *cpSuite) TestCopyPreserveAllSyncCpFailure(c *C) { dir := c.MkDir() mocked := testutil.MockCommand(c, "cp", "echo OUCH: cp failed.;exit 42").Also("sync", "") defer mocked.Restore() src := filepath.Join(dir, "meep") dst := filepath.Join(dir, "copied-meep") err := ioutil.WriteFile(src, []byte(nil), 0644) c.Assert(err, IsNil) err = CopyFile(src, dst, CopyFlagPreserveAll|CopyFlagSync) c.Assert(err, ErrorMatches, `failed to copy all: "OUCH: cp failed." \(42\)`) c.Check(mocked.Calls(), DeepEquals, [][]string{ {"cp", "-av", src, dst}, }) }
func (s *uDevSuite) TestReloadUDevRulesReportsErrorsFromReloadRules(c *C) { cmd := testutil.MockCommand(c, "udevadm", ` if [ "$1" = "control" ]; then echo "failure 1" exit 1 fi `) defer cmd.Restore() err := udev.ReloadRules() c.Assert(err.Error(), Equals, ""+ "cannot reload udev rules: exit status 1\n"+ "udev output:\n"+ "failure 1\n") c.Assert(cmd.Calls(), DeepEquals, [][]string{ {"udevadm", "control", "--reload-rules"}, }) }
func (s *copydataSuite) TestCopyDataCopyFailure(c *C) { v1 := snaptest.MockSnap(c, helloYaml1, helloContents, &snap.SideInfo{Revision: snap.R(10)}) s.populateData(c, snap.R(10)) // pretend we install a new version v2 := snaptest.MockSnap(c, helloYaml2, helloContents, &snap.SideInfo{Revision: snap.R(20)}) defer testutil.MockCommand(c, "cp", "echo cp: boom; exit 3").Restore() q := func(s string) string { return regexp.QuoteMeta(strconv.Quote(s)) } // copy data will fail err := s.be.CopySnapData(v2, v1, &s.nullProgress) c.Assert(err, ErrorMatches, fmt.Sprintf(`cannot copy %s to %s: .*: "cp: boom" \(3\)`, q(v1.DataDir()), q(v2.DataDir()))) }
func (s *cpSuite) TestCopySpecialFileSimple(c *C) { sync := testutil.MockCommand(c, "sync", "") defer sync.Restore() src := filepath.Join(c.MkDir(), "fifo") err := syscall.Mkfifo(src, 0644) c.Assert(err, IsNil) dir := c.MkDir() dst := filepath.Join(dir, "copied-fifo") err = CopySpecialFile(src, dst) c.Assert(err, IsNil) st, err := os.Stat(dst) c.Assert(err, IsNil) c.Check((st.Mode() & os.ModeNamedPipe), Equals, os.ModeNamedPipe) c.Check(sync.Calls(), DeepEquals, [][]string{{"sync", dir}}) }
func (s *cpSuite) TestCopyPreserveAllSync(c *C) { dir := c.MkDir() mocked := testutil.MockCommand(c, "cp", "").Also("sync", "") defer mocked.Restore() src := filepath.Join(dir, "meep") dst := filepath.Join(dir, "copied-meep") err := ioutil.WriteFile(src, []byte(nil), 0644) c.Assert(err, IsNil) err = CopyFile(src, dst, CopyFlagPreserveAll|CopyFlagSync) c.Assert(err, IsNil) c.Check(mocked.Calls(), DeepEquals, [][]string{ {"cp", "-av", src, dst}, {"sync"}, }) }
func (s *hookManagerSuite) SetUpTest(c *C) { dirs.SetRootDir(c.MkDir()) s.state = state.New(nil) manager, err := hookstate.Manager(s.state) c.Assert(err, IsNil) s.manager = manager hooksup := &hookstate.HookSetup{ Snap: "test-snap", Hook: "configure", Revision: snap.R(1), } initialContext := map[string]interface{}{ "test-key": "test-value", } s.state.Lock() s.task = hookstate.HookTask(s.state, "test summary", hooksup, initialContext) c.Assert(s.task, NotNil, Commentf("Expected HookTask to return a task")) s.change = s.state.NewChange("kind", "summary") s.change.AddTask(s.task) sideInfo := &snap.SideInfo{RealName: "test-snap", SnapID: "some-snap-id", Revision: snap.R(1)} snaptest.MockSnap(c, snapYaml, snapContents, sideInfo) snapstate.Set(s.state, "test-snap", &snapstate.SnapState{ Active: true, Sequence: []*snap.SideInfo{sideInfo}, Current: snap.R(1), }) s.state.Unlock() s.command = testutil.MockCommand(c, "snap", "") s.context = nil s.mockHandler = hooktest.NewMockHandler() s.manager.Register(regexp.MustCompile("configure"), func(context *hookstate.Context) hookstate.Handler { s.context = context return s.mockHandler }) }
func (s *hookManagerSuite) TestHookTaskHandlesHookError(c *C) { // Force the snap command to exit 1, and print something to stderr s.command = testutil.MockCommand( c, "snap", ">&2 echo 'hook failed at user request'; exit 1") s.manager.Ensure() s.manager.Wait() s.state.Lock() defer s.state.Unlock() c.Check(s.mockHandler.BeforeCalled, Equals, true) c.Check(s.mockHandler.DoneCalled, Equals, false) c.Check(s.mockHandler.ErrorCalled, Equals, true) c.Check(s.task.Kind(), Equals, "run-hook") c.Check(s.task.Status(), Equals, state.ErrorStatus) c.Check(s.change.Status(), Equals, state.ErrorStatus) checkTaskLogContains(c, s.task, ".*failed at user request.*") }
func (s *hookManagerSuite) TestHookTaskCorrectlyIncludesContext(c *C) { // Force the snap command to exit with a failure and print to stderr so we // can catch and verify it. s.command = testutil.MockCommand( c, "snap", ">&2 echo \"SNAP_CONTEXT=$SNAP_CONTEXT\"; exit 1") s.manager.Ensure() s.manager.Wait() s.state.Lock() defer s.state.Unlock() c.Check(s.mockHandler.BeforeCalled, Equals, true) c.Check(s.mockHandler.DoneCalled, Equals, false) c.Check(s.mockHandler.ErrorCalled, Equals, true) c.Check(s.task.Kind(), Equals, "run-hook") c.Check(s.task.Status(), Equals, state.ErrorStatus) c.Check(s.change.Status(), Equals, state.ErrorStatus) checkTaskLogContains(c, s.task, `.*SNAP_CONTEXT=\S+`) }
func (s *hookManagerSuite) TestHookTaskHandlerErrorError(c *C) { s.mockHandler.ErrorError = true // Force the snap command to simply exit 1, so the handler Error() runs s.command = testutil.MockCommand(c, "snap", "exit 1") s.manager.Ensure() s.manager.Wait() s.state.Lock() defer s.state.Unlock() c.Check(s.mockHandler.BeforeCalled, Equals, true) c.Check(s.mockHandler.DoneCalled, Equals, false) c.Check(s.mockHandler.ErrorCalled, Equals, true) c.Check(s.task.Kind(), Equals, "run-hook") c.Check(s.task.Status(), Equals, state.ErrorStatus) c.Check(s.change.Status(), Equals, state.ErrorStatus) checkTaskLogContains(c, s.task, `.*Error failed at user request.*`) }