func (s *snapmgrTestSuite) TestAliasSnapCommandSpaceConflict(c *C) { s.state.Lock() defer s.state.Unlock() snapstate.Set(s.state, "alias-snap", &snapstate.SnapState{ Sequence: []*snap.SideInfo{ {RealName: "alias-snap", Revision: snap.R(11)}, }, Current: snap.R(11), Active: true, }) // the command namespace of this one will conflict snapstate.Set(s.state, "alias1", &snapstate.SnapState{ Sequence: []*snap.SideInfo{ {RealName: "alias1", Revision: snap.R(3)}, }, Current: snap.R(3), }) chg := s.state.NewChange("alias", "enable an alias") ts, err := snapstate.Alias(s.state, "alias-snap", []string{"alias1.cmd1"}) c.Assert(err, IsNil) chg.AddAll(ts) s.state.Unlock() s.snapmgr.Ensure() s.snapmgr.Wait() s.state.Lock() c.Check(chg.Status(), Equals, state.ErrorStatus) c.Check(chg.Err(), ErrorMatches, `(?s).*cannot enable alias "alias1.cmd1" for "alias-snap", it conflicts with the command namespace of installed snap "alias1".*`) }
func (s *snapmgrTestSuite) TestAliasNoAlias(c *C) { s.state.Lock() defer s.state.Unlock() snapstate.Set(s.state, "some-snap", &snapstate.SnapState{ Sequence: []*snap.SideInfo{ {RealName: "some-snap", Revision: snap.R(11)}, }, Current: snap.R(11), Active: true, }) chg := s.state.NewChange("alias", "enable an alias") ts, err := snapstate.Alias(s.state, "some-snap", []string{"alias1"}) c.Assert(err, IsNil) chg.AddAll(ts) s.state.Unlock() s.snapmgr.Ensure() s.snapmgr.Wait() s.state.Lock() c.Check(chg.Status(), Equals, state.ErrorStatus) c.Check(chg.Err(), ErrorMatches, `(?s).*cannot enable alias "alias1" for "some-snap", no such alias.*`) }
func (s *discardSnapSuite) TestDoDiscardSnapErrorsForActive(c *C) { s.state.Lock() snapstate.Set(s.state, "foo", &snapstate.SnapState{ Sequence: []*snap.SideInfo{ {RealName: "foo", Revision: snap.R(3)}, }, Current: snap.R(3), Active: true, SnapType: "app", }) t := s.state.NewTask("discard-snap", "test") t.Set("snap-setup", &snapstate.SnapSetup{ SideInfo: &snap.SideInfo{ RealName: "foo", Revision: snap.R(3), }, }) chg := s.state.NewChange("dummy", "...") chg.AddTask(t) s.state.Unlock() s.snapmgr.Ensure() s.snapmgr.Wait() s.state.Lock() defer s.state.Unlock() c.Check(chg.Status(), Equals, state.ErrorStatus) c.Check(chg.Err(), ErrorMatches, `(?s).*internal error: cannot discard snap "foo": still active.*`) }
func (bs *bootedSuite) TestUpdateBootRevisionsOSErrorsLate(c *C) { st := bs.state st.Lock() defer st.Unlock() // put core into the state but add no files on disk // will break in the tasks snapstate.Set(st, "core", &snapstate.SnapState{ SnapType: "os", Active: true, Sequence: []*snap.SideInfo{osSI1, osSI2}, Current: snap.R(2), }) bs.fakeBackend.linkSnapFailTrigger = filepath.Join(dirs.SnapMountDir, "/core/1") bs.bootloader.BootVars["snap_kernel"] = "core_1.snap" err := snapstate.UpdateBootRevisions(st) c.Assert(err, IsNil) st.Unlock() bs.settle() st.Lock() c.Assert(st.Changes(), HasLen, 1) chg := st.Changes()[0] c.Assert(chg.Kind(), Equals, "update-revisions") c.Assert(chg.IsReady(), Equals, true) c.Assert(chg.Err(), ErrorMatches, `(?ms).*Make snap "core" \(1\) available to the system \(fail\).*`) }
func (s *snapmgrTestSuite) TestAliasAutoAliasConflict(c *C) { s.state.Lock() defer s.state.Unlock() snapstate.Set(s.state, "alias-snap", &snapstate.SnapState{ Sequence: []*snap.SideInfo{ {RealName: "alias-snap", Revision: snap.R(11)}, }, Current: snap.R(11), Active: true, }) s.state.Set("aliases", map[string]map[string]string{ "other-snap": {"alias1": "auto"}, }) chg := s.state.NewChange("alias", "enable an alias") ts, err := snapstate.Alias(s.state, "alias-snap", []string{"alias1"}) c.Assert(err, IsNil) chg.AddAll(ts) s.state.Unlock() s.snapmgr.Ensure() s.snapmgr.Wait() s.state.Lock() c.Check(chg.Status(), Equals, state.ErrorStatus) c.Check(chg.Err(), ErrorMatches, `(?s).*cannot enable alias "alias1" for "alias-snap", already enabled for "other-snap".*`) }
func (s *interfaceManagerSuite) mockSnap(c *C, yamlText string) *snap.Info { sideInfo := &snap.SideInfo{ Revision: snap.R(1), } snapInfo := snaptest.MockSnap(c, yamlText, "", sideInfo) sideInfo.RealName = snapInfo.Name() a, err := s.db.FindMany(asserts.SnapDeclarationType, map[string]string{ "snap-name": sideInfo.RealName, }) if err == nil { decl := a[0].(*asserts.SnapDeclaration) snapInfo.SnapID = decl.SnapID() sideInfo.SnapID = decl.SnapID() } else if err == asserts.ErrNotFound { err = nil } c.Assert(err, IsNil) s.state.Lock() defer s.state.Unlock() // Put a side info into the state snapstate.Set(s.state, snapInfo.Name(), &snapstate.SnapState{ Active: true, Sequence: []*snap.SideInfo{sideInfo}, Current: sideInfo.Revision, }) return snapInfo }
func (s *discardSnapSuite) TestDoDiscardSnapToEmpty(c *C) { s.state.Lock() snapstate.Set(s.state, "foo", &snapstate.SnapState{ Sequence: []*snap.SideInfo{ {RealName: "foo", Revision: snap.R(3)}, }, Current: snap.R(3), SnapType: "app", }) t := s.state.NewTask("discard-snap", "test") t.Set("snap-setup", &snapstate.SnapSetup{ SideInfo: &snap.SideInfo{ RealName: "foo", Revision: snap.R(33), }, }) s.state.NewChange("dummy", "...").AddTask(t) s.state.Unlock() s.snapmgr.Ensure() s.snapmgr.Wait() s.state.Lock() defer s.state.Unlock() var snapst snapstate.SnapState err := snapstate.Get(s.state, "foo", &snapst) c.Assert(err, Equals, state.ErrNoState) }
func (s *mountSnapSuite) TestDoUndoMountSnap(c *C) { v1 := "name: core\nversion: 1.0\n" testSnap := snaptest.MakeTestSnapWithFiles(c, v1, nil) s.state.Lock() defer s.state.Unlock() si1 := &snap.SideInfo{ RealName: "core", Revision: snap.R(1), } si2 := &snap.SideInfo{ RealName: "core", Revision: snap.R(2), } snapstate.Set(s.state, "core", &snapstate.SnapState{ Sequence: []*snap.SideInfo{si1}, Current: si1.Revision, SnapType: "os", }) t := s.state.NewTask("mount-snap", "test") t.Set("snap-setup", &snapstate.SnapSetup{ SideInfo: si2, SnapPath: testSnap, }) chg := s.state.NewChange("dummy", "...") chg.AddTask(t) terr := s.state.NewTask("error-trigger", "provoking total undo") terr.WaitFor(t) chg.AddTask(terr) s.state.Unlock() for i := 0; i < 3; i++ { s.snapmgr.Ensure() s.snapmgr.Wait() } s.state.Lock() // ensure undo was called the right way c.Check(s.fakeBackend.ops, DeepEquals, fakeOps{ { op: "current", old: "/snap/core/1", }, { op: "setup-snap", name: testSnap, revno: snap.R(2), }, { op: "undo-setup-snap", name: "/snap/core/2", stype: "os", }, }) }
func (s *apiSuite) mockSnap(c *C, yamlText string) *snap.Info { if s.d == nil { panic("call s.daemon(c) in your test first") } snapInfo := snaptest.MockSnap(c, yamlText, &snap.SideInfo{Revision: snap.R(1)}) snap.AddImplicitSlots(snapInfo) st := s.d.overlord.State() st.Lock() defer st.Unlock() // Put a side info into the state snapstate.Set(st, snapInfo.Name(), &snapstate.SnapState{ Active: true, Sequence: []*snap.SideInfo{ { RealName: snapInfo.Name(), Revision: snapInfo.Revision, SnapID: "ididid", }, }, Current: snapInfo.Revision, }) // Put the snap into the interface repository repo := s.d.overlord.InterfaceManager().Repository() err := repo.AddSnap(snapInfo) c.Assert(err, IsNil) return snapInfo }
func (s *snapmgrTestSuite) TestDoUndoSetAutoAliases(c *C) { s.state.Lock() defer s.state.Unlock() snapstate.AutoAliases = func(st *state.State, info *snap.Info) ([]string, error) { c.Check(info.Name(), Equals, "alias-snap") return []string{"alias1", "alias2", "alias4", "alias5"}, nil } snapstate.Set(s.state, "alias-snap", &snapstate.SnapState{ Sequence: []*snap.SideInfo{ {RealName: "alias-snap", Revision: snap.R(11)}, }, Current: snap.R(11), Active: true, }) s.state.Set("aliases", map[string]map[string]string{ "alias-snap": { "alias1": "enabled", "alias2": "auto", "alias3": "auto", "alias5": "disabled", }, }) t := s.state.NewTask("set-auto-aliases", "test") t.Set("snap-setup", &snapstate.SnapSetup{ SideInfo: &snap.SideInfo{RealName: "alias-snap"}, }) chg := s.state.NewChange("dummy", "...") chg.AddTask(t) terr := s.state.NewTask("error-trigger", "provoking total undo") terr.WaitFor(t) chg.AddTask(terr) s.state.Unlock() for i := 0; i < 3; i++ { s.snapmgr.Ensure() s.snapmgr.Wait() } s.state.Lock() c.Check(t.Status(), Equals, state.UndoneStatus, Commentf("%v", chg.Err())) var allAliases map[string]map[string]string err := s.state.Get("aliases", &allAliases) c.Assert(err, IsNil) c.Check(allAliases, DeepEquals, map[string]map[string]string{ "alias-snap": { "alias1": "enabled", "alias2": "auto", "alias3": "auto", "alias5": "disabled", }, }) }
func (s *deviceMgrSuite) TestDeviceManagerEnsureBootOkUpdateBootRevisionsHappy(c *C) { release.OnClassic = false bootloader := boottest.NewMockBootloader("mock", c.MkDir()) partition.ForceBootloader(bootloader) defer partition.ForceBootloader(nil) // simulate that we have a new core_2, tried to boot it but that failed bootloader.SetBootVars(map[string]string{ "snap_mode": "", "snap_try_core": "core_2.snap", "snap_core": "core_1.snap", }) s.state.Lock() defer s.state.Unlock() siCore1 := &snap.SideInfo{RealName: "core", Revision: snap.R(1)} siCore2 := &snap.SideInfo{RealName: "core", Revision: snap.R(2)} snapstate.Set(s.state, "core", &snapstate.SnapState{ SnapType: "os", Active: true, Sequence: []*snap.SideInfo{siCore1, siCore2}, Current: siCore2.Revision, }) s.state.Unlock() err := s.mgr.EnsureBootOk() s.state.Lock() c.Assert(err, IsNil) c.Check(s.state.Changes(), HasLen, 1) c.Check(s.state.Changes()[0].Kind(), Equals, "update-revisions") }
func (s *deviceMgrSuite) TestDeviceManagerEnsureBootOkBootloaderHappy(c *C) { release.OnClassic = false bootloader := boottest.NewMockBootloader("mock", c.MkDir()) partition.ForceBootloader(bootloader) defer partition.ForceBootloader(nil) bootloader.SetBootVars(map[string]string{ "snap_mode": "trying", "snap_try_core": "core_1.snap", }) s.state.Lock() defer s.state.Unlock() siCore1 := &snap.SideInfo{RealName: "core", Revision: snap.R(1)} snapstate.Set(s.state, "core", &snapstate.SnapState{ SnapType: "os", Active: true, Sequence: []*snap.SideInfo{siCore1}, Current: siCore1.Revision, }) s.state.Unlock() err := s.mgr.EnsureBootOk() s.state.Lock() c.Assert(err, IsNil) m, err := bootloader.GetBootVars("snap_mode") c.Assert(err, IsNil) c.Assert(m, DeepEquals, map[string]string{"snap_mode": ""}) }
func (s *snapmgrTestSuite) TestDoUndoSetupAliases(c *C) { s.state.Lock() defer s.state.Unlock() snapstate.Set(s.state, "alias-snap", &snapstate.SnapState{ Sequence: []*snap.SideInfo{ {RealName: "alias-snap", Revision: snap.R(11)}, }, Current: snap.R(11), Active: true, }) s.state.Set("aliases", map[string]map[string]string{ "alias-snap": { "alias1": "enabled", }, }) t := s.state.NewTask("setup-aliases", "test") t.Set("snap-setup", &snapstate.SnapSetup{ SideInfo: &snap.SideInfo{RealName: "alias-snap"}, }) chg := s.state.NewChange("dummy", "...") chg.AddTask(t) terr := s.state.NewTask("error-trigger", "provoking total undo") terr.WaitFor(t) chg.AddTask(terr) s.state.Unlock() for i := 0; i < 3; i++ { s.snapmgr.Ensure() s.snapmgr.Wait() } s.state.Lock() c.Check(t.Status(), Equals, state.UndoneStatus) expected := fakeOps{ { op: "update-aliases", aliases: []*backend.Alias{{"alias1", "alias-snap.cmd1"}}, }, { op: "matching-aliases", aliases: []*backend.Alias{{"alias1", "alias-snap.cmd1"}}, }, { op: "update-aliases", rmAliases: []*backend.Alias{{"alias1", "alias-snap.cmd1"}}, }, } // start with an easier-to-read error if this fails: c.Assert(s.fakeBackend.ops.Ops(), DeepEquals, expected.Ops()) c.Assert(s.fakeBackend.ops, DeepEquals, expected) }
func (s *snapmgrTestSuite) TestAutoAliasesDeltaAll(c *C) { seen := make(map[string]bool) snapstate.AutoAliases = func(st *state.State, info *snap.Info) ([]string, error) { seen[info.Name()] = true if info.Name() == "alias-snap" { return []string{"alias1", "alias2", "alias4", "alias5"}, nil } return nil, nil } s.state.Lock() defer s.state.Unlock() snapstate.Set(s.state, "alias-snap", &snapstate.SnapState{ Sequence: []*snap.SideInfo{ {RealName: "alias-snap", Revision: snap.R(11)}, }, Current: snap.R(11), Active: true, }) snapstate.Set(s.state, "other-snap", &snapstate.SnapState{ Sequence: []*snap.SideInfo{ {RealName: "other-snap", Revision: snap.R(2)}, }, Current: snap.R(2), Active: true, }) new, retired, err := snapstate.AutoAliasesDelta(s.state, nil) c.Assert(err, IsNil) c.Check(new, DeepEquals, map[string][]string{ "alias-snap": {"alias1", "alias2", "alias4", "alias5"}, }) c.Check(retired, HasLen, 0) c.Check(seen, DeepEquals, map[string]bool{ "alias-snap": true, "other-snap": true, }) }
func (bs *bootedSuite) makeInstalledKernelOS(c *C, st *state.State) { snaptest.MockSnap(c, "name: core\ntype: os\nversion: 1", osSI1) snaptest.MockSnap(c, "name: core\ntype: os\nversion: 2", osSI2) snapstate.Set(st, "core", &snapstate.SnapState{ SnapType: "os", Active: true, Sequence: []*snap.SideInfo{osSI1, osSI2}, Current: snap.R(2), }) snaptest.MockSnap(c, "name: canonical-pc-linux\ntype: os\nversion: 1", kernelSI1) snaptest.MockSnap(c, "name: canonical-pc-linux\ntype: os\nversion: 2", kernelSI2) snapstate.Set(st, "canonical-pc-linux", &snapstate.SnapState{ SnapType: "kernel", Active: true, Sequence: []*snap.SideInfo{kernelSI1, kernelSI2}, Current: snap.R(2), }) }
func (s *assertMgrSuite) stateFromDecl(decl *asserts.SnapDeclaration, revno snap.Revision) { name := decl.SnapName() snapID := decl.SnapID() snapstate.Set(s.state, name, &snapstate.SnapState{ Active: true, Sequence: []*snap.SideInfo{ {RealName: name, SnapID: snapID, Revision: revno}, }, Current: revno, }) }
func (s *deviceMgrSuite) setupGadget(c *C, snapYaml string, snapContents string) { sideInfoGadget := &snap.SideInfo{ RealName: "gadget", Revision: snap.R(2), } snaptest.MockSnap(c, snapYaml, snapContents, sideInfoGadget) snapstate.Set(s.state, "gadget", &snapstate.SnapState{ SnapType: "gadget", Active: true, Sequence: []*snap.SideInfo{sideInfoGadget}, Current: sideInfoGadget.Revision, }) }
func (s *deviceMgrSuite) setupCore(c *C, name, snapYaml string, snapContents string) { sideInfoCore := &snap.SideInfo{ RealName: name, Revision: snap.R(3), } snaptest.MockSnap(c, snapYaml, snapContents, sideInfoCore) snapstate.Set(s.state, name, &snapstate.SnapState{ SnapType: "os", Active: true, Sequence: []*snap.SideInfo{sideInfoCore}, Current: sideInfoCore.Revision, }) }
func (s *interfaceManagerSuite) testUndoDicardConns(c *C, snapName string) { s.state.Lock() // Store information about a connection in the state. s.state.Set("conns", map[string]interface{}{ "consumer:plug producer:slot": map[string]interface{}{"interface": "test"}, }) // Store empty snap state. This snap has an empty sequence now. snapstate.Set(s.state, snapName, &snapstate.SnapState{}) s.state.Unlock() mgr := s.manager(c) // Run the discard-conns task and let it finish change := s.addDiscardConnsChange(c, snapName) // Add a dummy task just to hold the change not ready. s.state.Lock() dummy := s.state.NewTask("dummy", "") change.AddTask(dummy) s.state.Unlock() mgr.Ensure() mgr.Wait() s.state.Lock() c.Check(change.Status(), Equals, state.DoStatus) change.Abort() s.state.Unlock() mgr.Ensure() mgr.Wait() mgr.Stop() s.state.Lock() defer s.state.Unlock() c.Assert(change.Status(), Equals, state.UndoneStatus) // Information about the connection is intact var conns map[string]interface{} err := s.state.Get("conns", &conns) c.Assert(err, IsNil) c.Check(conns, DeepEquals, map[string]interface{}{ "consumer:plug producer:slot": map[string]interface{}{"interface": "test"}, }) var removed map[string]interface{} err = change.Tasks()[0].Get("removed", &removed) c.Assert(err, IsNil) c.Check(removed, HasLen, 0) }
func (s *interfaceManagerSuite) mockUpdatedSnap(c *C, yamlText string, revision int) *snap.Info { sideInfo := &snap.SideInfo{Revision: snap.R(revision)} snapInfo := snaptest.MockSnap(c, yamlText, "", sideInfo) sideInfo.RealName = snapInfo.Name() s.state.Lock() defer s.state.Unlock() // Put the new revision (stored in SideInfo) into the state var snapst snapstate.SnapState err := snapstate.Get(s.state, snapInfo.Name(), &snapst) c.Assert(err, IsNil) snapst.Sequence = append(snapst.Sequence, sideInfo) snapstate.Set(s.state, snapInfo.Name(), &snapst) return snapInfo }
func (s *snapmgrTestSuite) TestDoSetAutoAliasesConflict(c *C) { s.state.Lock() defer s.state.Unlock() snapstate.AutoAliases = func(st *state.State, info *snap.Info) ([]string, error) { c.Check(info.Name(), Equals, "alias-snap") return []string{"alias1", "alias2", "alias4", "alias5"}, nil } snapstate.Set(s.state, "alias-snap", &snapstate.SnapState{ Sequence: []*snap.SideInfo{ {RealName: "alias-snap", Revision: snap.R(11)}, }, Current: snap.R(11), Active: true, }) s.state.Set("aliases", map[string]map[string]string{ "alias-snap": { "alias1": "enabled", "alias3": "auto", "alias5": "disabled", }, "other-snap": { "alias4": "enabled", }, }) t := s.state.NewTask("set-auto-aliases", "test") t.Set("snap-setup", &snapstate.SnapSetup{ SideInfo: &snap.SideInfo{RealName: "alias-snap"}, }) chg := s.state.NewChange("dummy", "...") chg.AddTask(t) s.state.Unlock() s.snapmgr.Ensure() s.snapmgr.Wait() s.state.Lock() c.Check(t.Status(), Equals, state.ErrorStatus, Commentf("%v", chg.Err())) c.Check(chg.Err(), ErrorMatches, `(?s).*cannot enable alias "alias4" for "alias-snap", already enabled for "other-snap".*`) }
func (bs *bootedSuite) TestUpdateRevisionsOSErrorsLate(c *C) { st := bs.overlord.State() st.Lock() // put ubuntu-core into the state but add no files on disk // will break in the tasks snapstate.Set(st, "ubuntu-core", &snapstate.SnapState{ SnapType: "os", Active: true, Sequence: []*snap.SideInfo{osSI1, osSI2}, Current: snap.R(2), }) st.Unlock() bs.bootloader.BootVars["snap_kernel"] = "ubuntu-core_1.snap" err := boot.UpdateRevisions(bs.overlord) c.Assert(err, ErrorMatches, `(?ms)cannot update revisions after boot changes:.*`) }
func (s *interfaceManagerSuite) mockSnap(c *C, yamlText string) *snap.Info { sideInfo := &snap.SideInfo{ Revision: snap.R(1), } snapInfo := snaptest.MockSnap(c, yamlText, sideInfo) sideInfo.RealName = snapInfo.Name() s.state.Lock() defer s.state.Unlock() // Put a side info into the state snapstate.Set(s.state, snapInfo.Name(), &snapstate.SnapState{ Active: true, Sequence: []*snap.SideInfo{sideInfo}, Current: sideInfo.Revision, }) return snapInfo }
func (s *snapmgrTestSuite) TestAliasUpdateChangeConflict(c *C) { s.state.Lock() defer s.state.Unlock() snapstate.Set(s.state, "some-snap", &snapstate.SnapState{ Active: true, Sequence: []*snap.SideInfo{{RealName: "some-snap", SnapID: "some-snap-id", Revision: snap.R(7)}}, Current: snap.R(7), SnapType: "app", }) ts, err := snapstate.Alias(s.state, "some-snap", []string{"alias1"}) c.Assert(err, IsNil) // need a change to make the tasks visible s.state.NewChange("alias", "...").AddAll(ts) _, err = snapstate.Update(s.state, "some-snap", "some-channel", snap.R(0), s.user.ID, snapstate.Flags{}) c.Assert(err, ErrorMatches, `snap "some-snap" has changes in progress`) }
func (s *linkSnapSuite) TestDoUndoLinkSnapSequenceHadCandidate(c *C) { s.state.Lock() defer s.state.Unlock() si1 := &snap.SideInfo{ RealName: "foo", Revision: snap.R(1), } si2 := &snap.SideInfo{ RealName: "foo", Revision: snap.R(2), } snapstate.Set(s.state, "foo", &snapstate.SnapState{ Sequence: []*snap.SideInfo{si1, si2}, Current: si2.Revision, }) t := s.state.NewTask("link-snap", "test") t.Set("snap-setup", &snapstate.SnapSetup{ SideInfo: si1, Channel: "beta", }) chg := s.state.NewChange("dummy", "...") chg.AddTask(t) terr := s.state.NewTask("error-trigger", "provoking total undo") terr.WaitFor(t) chg.AddTask(terr) s.state.Unlock() for i := 0; i < 3; i++ { s.snapmgr.Ensure() s.snapmgr.Wait() } s.state.Lock() var snapst snapstate.SnapState err := snapstate.Get(s.state, "foo", &snapst) c.Assert(err, IsNil) c.Check(snapst.Active, Equals, false) c.Check(snapst.Sequence, HasLen, 2) c.Check(snapst.Current, Equals, snap.R(2)) c.Check(t.Status(), Equals, state.UndoneStatus) }
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 *snapmgrTestSuite) TestAliasTasks(c *C) { s.state.Lock() defer s.state.Unlock() snapstate.Set(s.state, "some-snap", &snapstate.SnapState{ Sequence: []*snap.SideInfo{ {RealName: "some-snap", Revision: snap.R(11)}, }, Current: snap.R(11), Active: true, }) ts, err := snapstate.Alias(s.state, "some-snap", []string{"alias"}) c.Assert(err, IsNil) c.Assert(s.state.TaskCount(), Equals, len(ts.Tasks())) c.Assert(taskKinds(ts.Tasks()), DeepEquals, []string{ "alias", }) }
func (s *checkSnapSuite) TestCheckSnapKernelAdditionProhibitedBySnapID(c *C) { reset := release.MockOnClassic(false) defer reset() st := state.New(nil) st.Lock() defer st.Unlock() si := &snap.SideInfo{RealName: "kernel", Revision: snap.R(2), SnapID: "kernel-id"} snaptest.MockSnap(c, ` name: kernel type: kernel version: 1 `, si) snapstate.Set(st, "kernel", &snapstate.SnapState{ SnapType: "kernel", Active: true, Sequence: []*snap.SideInfo{si}, Current: si.Revision, }) const yaml = `name: zkernel type: kernel version: 2 ` info, err := snap.InfoFromSnapYaml([]byte(yaml)) info.SnapID = "zkernel-id" c.Assert(err, IsNil) var openSnapFile = func(path string, si *snap.SideInfo) (*snap.Info, snap.Container, error) { return info, nil, nil } restore := snapstate.MockOpenSnapFile(openSnapFile) defer restore() st.Unlock() err = snapstate.CheckSnap(st, "snap-path", nil, nil, snapstate.Flags{}) st.Lock() c.Check(err, ErrorMatches, "cannot replace kernel snap with a different one") }
func (s *checkSnapSuite) TestCheckSnapGadgetUpdateLocal(c *C) { reset := release.MockOnClassic(false) defer reset() st := state.New(nil) st.Lock() defer st.Unlock() si := &snap.SideInfo{RealName: "gadget", Revision: snap.R(2)} snaptest.MockSnap(c, ` name: gadget type: gadget version: 1 `, si) snapstate.Set(st, "gadget", &snapstate.SnapState{ SnapType: "gadget", Active: true, Sequence: []*snap.SideInfo{si}, Current: si.Revision, }) const yaml = `name: gadget type: gadget version: 2 ` info, err := snap.InfoFromSnapYaml([]byte(yaml)) // no SnapID => local! c.Assert(err, IsNil) var openSnapFile = func(path string, si *snap.SideInfo) (*snap.Info, snap.Container, error) { return info, nil, nil } restore := snapstate.MockOpenSnapFile(openSnapFile) defer restore() st.Unlock() err = snapstate.CheckSnap(st, "snap-path", nil, nil, snapstate.Flags{}) st.Lock() c.Check(err, IsNil) }
// Test that setup-snap-security gets undone correctly when a snap is installed // but the installation fails (the security profiles are removed). func (s *interfaceManagerSuite) TestUndoSetupProfilesOnInstall(c *C) { // Create the interface manager mgr := s.manager(c) // Mock a snap and remove the side info from the state (it is implicitly // added by mockSnap) so that we can emulate a undo during a fresh // install. snapInfo := s.mockSnap(c, sampleSnapYaml) s.state.Lock() snapstate.Set(s.state, snapInfo.Name(), nil) s.state.Unlock() // Add a change that undoes "setup-snap-security" change := s.addSetupSnapSecurityChange(c, &snapstate.SnapSetup{ SideInfo: &snap.SideInfo{ RealName: snapInfo.Name(), Revision: snapInfo.Revision, }, }) s.state.Lock() change.Tasks()[0].SetStatus(state.UndoStatus) s.state.Unlock() // Turn the crank mgr.Ensure() mgr.Wait() mgr.Stop() s.state.Lock() defer s.state.Unlock() // Ensure that the change got undone. c.Assert(change.Err(), IsNil) c.Check(change.Status(), Equals, state.UndoneStatus) // Ensure that since we had no prior revisions of this snap installed the // undo task removed the security profile from the system. c.Assert(s.secBackend.SetupCalls, HasLen, 0) c.Assert(s.secBackend.RemoveCalls, HasLen, 1) c.Check(s.secBackend.RemoveCalls, DeepEquals, []string{snapInfo.Name()}) }