func (s *assertMgrSuite) TestValidateRefreshesNoControl(c *C) { s.state.Lock() defer s.state.Unlock() snapDeclFoo := s.snapDecl(c, "foo", nil) snapDeclBar := s.snapDecl(c, "bar", nil) s.stateFromDecl(snapDeclFoo, snap.R(7)) s.stateFromDecl(snapDeclBar, snap.R(3)) err := assertstate.Add(s.state, s.storeSigning.StoreAccountKey("")) c.Assert(err, IsNil) err = assertstate.Add(s.state, s.dev1Acct) c.Assert(err, IsNil) err = assertstate.Add(s.state, snapDeclFoo) c.Assert(err, IsNil) err = assertstate.Add(s.state, snapDeclBar) c.Assert(err, IsNil) fooRefresh := &snap.Info{ SideInfo: snap.SideInfo{RealName: "foo", SnapID: "foo-id", Revision: snap.R(9)}, } validated, err := assertstate.ValidateRefreshes(s.state, []*snap.Info{fooRefresh}, 0) c.Assert(err, IsNil) c.Check(validated, DeepEquals, []*snap.Info{fooRefresh}) }
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 (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 *copydataSuite) TestCopyDataDoUndoNoUserHomes(c *C) { // this home dir path does not exist oldSnapDataHomeGlob := dirs.SnapDataHomeGlob defer func() { dirs.SnapDataHomeGlob = oldSnapDataHomeGlob }() dirs.SnapDataHomeGlob = filepath.Join(s.tempdir, "no-such-home", "*", "snap") 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)}) // copy data err := s.be.CopySnapData(v2, v1, &s.nullProgress) c.Assert(err, IsNil) v2data := filepath.Join(dirs.SnapDataDir, "hello/20") l, err := filepath.Glob(filepath.Join(v2data, "*")) c.Assert(err, IsNil) c.Assert(l, HasLen, 1) err = s.be.UndoCopySnapData(v2, v1, &s.nullProgress) c.Assert(err, IsNil) // now removed _, err = os.Stat(v2data) c.Assert(os.IsNotExist(err), Equals, true) }
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 *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) 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 *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 revisionSuite) TestYAML(c *C) { for _, v := range []struct { n int s string }{ {0, "unset"}, {10, `"10"`}, {-9, "x9"}, } { r := snap.R(v.n) data, err := yaml.Marshal(snap.R(v.n)) c.Assert(err, IsNil) c.Assert(string(data), Equals, v.s+"\n") var got snap.Revision err = yaml.Unmarshal(data, &got) c.Assert(err, IsNil) c.Assert(got, Equals, r) got = snap.Revision{} err = json.Unmarshal([]byte(strconv.Itoa(r.N)), &got) c.Assert(err, IsNil) c.Assert(got, Equals, r) } }
// ensure that even with no home dir there is no error and the // system data gets copied func (s *copydataSuite) TestCopyDataNoUserHomes(c *C) { // this home dir path does not exist oldSnapDataHomeGlob := dirs.SnapDataHomeGlob defer func() { dirs.SnapDataHomeGlob = oldSnapDataHomeGlob }() dirs.SnapDataHomeGlob = filepath.Join(s.tempdir, "no-such-home", "*", "snap") v1 := snaptest.MockSnap(c, helloYaml1, helloContents, &snap.SideInfo{Revision: snap.R(10)}) err := s.be.CopySnapData(v1, nil, &s.nullProgress) c.Assert(err, IsNil) canaryDataFile := filepath.Join(v1.DataDir(), "canary.txt") err = ioutil.WriteFile(canaryDataFile, []byte(""), 0644) c.Assert(err, IsNil) canaryDataFile = filepath.Join(v1.CommonDataDir(), "canary.common") err = ioutil.WriteFile(canaryDataFile, []byte(""), 0644) c.Assert(err, IsNil) v2 := snaptest.MockSnap(c, helloYaml2, helloContents, &snap.SideInfo{Revision: snap.R(20)}) err = s.be.CopySnapData(v2, v1, &s.nullProgress) c.Assert(err, IsNil) _, err = os.Stat(filepath.Join(v2.DataDir(), "canary.txt")) c.Assert(err, IsNil) _, err = os.Stat(filepath.Join(v2.CommonDataDir(), "canary.common")) c.Assert(err, IsNil) // sanity atm c.Check(v1.DataDir(), Not(Equals), v2.DataDir()) c.Check(v1.CommonDataDir(), Equals, v2.CommonDataDir()) }
func (s *linkSnapSuite) TestDoLinkSnapSuccess(c *C) { s.state.Lock() t := s.state.NewTask("link-snap", "test") t.Set("snap-setup", &snapstate.SnapSetup{ SideInfo: &snap.SideInfo{ RealName: "foo", Revision: snap.R(33), }, Channel: "beta", }) 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, IsNil) typ, err := snapst.Type() c.Check(err, IsNil) c.Check(typ, Equals, snap.TypeApp) c.Check(snapst.Active, Equals, true) c.Check(snapst.Sequence, HasLen, 1) c.Check(snapst.Current, Equals, snap.R(33)) c.Check(snapst.Channel, Equals, "beta") c.Check(t.Status(), Equals, state.DoneStatus) c.Check(s.stateBackend.restartRequested, Equals, false) }
func (s *copydataSuite) TestCopyDataDoUndoABA(c *C) { v1 := snaptest.MockSnap(c, helloYaml1, helloContents, &snap.SideInfo{Revision: snap.R(10)}) s.populateData(c, snap.R(10)) c.Check(s.populatedData("10"), Equals, "10\n") // pretend we install a new version v2 := snaptest.MockSnap(c, helloYaml2, helloContents, &snap.SideInfo{Revision: snap.R(20)}) // and write our own data to it s.populateData(c, snap.R(20)) c.Check(s.populatedData("20"), Equals, "20\n") // and now we pretend to refresh back to v1 (r10) c.Check(s.be.CopySnapData(v1, v2, &s.nullProgress), IsNil) // so v1 (r10) now has v2 (r20)'s data and we have trash c.Check(s.populatedData("10"), Equals, "20\n") c.Check(s.populatedData("10.old"), Equals, "10\n") // but oh no! we have to undo it! c.Check(s.be.UndoCopySnapData(v1, v2, &s.nullProgress), IsNil) // so now v1 (r10) has v1 (r10)'s data and v2 (r20) has v2 (r20)'s data and we have no trash c.Check(s.populatedData("10"), Equals, "10\n") c.Check(s.populatedData("20"), Equals, "20\n") c.Check(s.populatedData("10.old"), Equals, "") }
func (s *copydataSuite) TestCopyDataDoIdempotent(c *C) { // make sure that a retry wouldn't stumble on partial work v1 := snaptest.MockSnap(c, helloYaml1, helloContents, &snap.SideInfo{Revision: snap.R(10)}) s.populateData(c, snap.R(10)) homedir := s.populateHomeData(c, "user1", snap.R(10)) // pretend we install a new version v2 := snaptest.MockSnap(c, helloYaml2, helloContents, &snap.SideInfo{Revision: snap.R(20)}) // copy data err := s.be.CopySnapData(v2, v1, &s.nullProgress) c.Assert(err, IsNil) err = s.be.CopySnapData(v2, v1, &s.nullProgress) c.Assert(err, IsNil) v2data := filepath.Join(dirs.SnapDataDir, "hello/20") l, err := filepath.Glob(filepath.Join(v2data, "*")) c.Assert(err, IsNil) c.Assert(l, HasLen, 1) v2HomeData := filepath.Join(homedir, "hello/20") l, err = filepath.Glob(filepath.Join(v2HomeData, "*")) c.Assert(err, IsNil) c.Assert(l, HasLen, 1) }
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 *copydataSuite) TestCopyDataUndoIdempotent(c *C) { // make sure that a retry wouldn't stumble on partial work v1 := snaptest.MockSnap(c, helloYaml1, helloContents, &snap.SideInfo{Revision: snap.R(10)}) s.populateData(c, snap.R(10)) homedir := s.populateHomeData(c, "user1", snap.R(10)) // pretend we install a new version v2 := snaptest.MockSnap(c, helloYaml2, helloContents, &snap.SideInfo{Revision: snap.R(20)}) // copy data err := s.be.CopySnapData(v2, v1, &s.nullProgress) c.Assert(err, IsNil) v2data := filepath.Join(dirs.SnapDataDir, "hello/20") err = s.be.UndoCopySnapData(v2, v1, &s.nullProgress) c.Assert(err, IsNil) err = s.be.UndoCopySnapData(v2, v1, &s.nullProgress) c.Assert(err, IsNil) // now removed _, err = os.Stat(v2data) c.Assert(os.IsNotExist(err), Equals, true) v2HomeData := filepath.Join(homedir, "hello/20") _, err = os.Stat(v2HomeData) c.Assert(os.IsNotExist(err), Equals, true) }
func (bs *bootedSuite) TestUpdateBootRevisionsKernelSimple(c *C) { st := bs.state st.Lock() defer st.Unlock() bs.makeInstalledKernelOS(c, st) bs.bootloader.BootVars["snap_kernel"] = "canonical-pc-linux_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.Err(), IsNil) c.Assert(chg.Kind(), Equals, "update-revisions") c.Assert(chg.IsReady(), Equals, true) // canonical-pc-linux "current" got reverted but core did not var snapst snapstate.SnapState err = snapstate.Get(st, "canonical-pc-linux", &snapst) c.Assert(err, IsNil) c.Assert(snapst.Current, Equals, snap.R(1)) c.Assert(snapst.Active, Equals, true) err = snapstate.Get(st, "core", &snapst) c.Assert(err, IsNil) c.Assert(snapst.Current, Equals, snap.R(2)) c.Assert(snapst.Active, Equals, true) }
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 *copydataSuite) TestCopyDataDoUndo(c *C) { v1 := snaptest.MockSnap(c, helloYaml1, helloContents, &snap.SideInfo{Revision: snap.R(10)}) s.populateData(c, snap.R(10)) homedir := s.populateHomeData(c, "user1", snap.R(10)) // pretend we install a new version v2 := snaptest.MockSnap(c, helloYaml2, helloContents, &snap.SideInfo{Revision: snap.R(20)}) // copy data err := s.be.CopySnapData(v2, v1, &s.nullProgress) c.Assert(err, IsNil) v2data := filepath.Join(dirs.SnapDataDir, "hello/20") l, err := filepath.Glob(filepath.Join(v2data, "*")) c.Assert(err, IsNil) c.Assert(l, HasLen, 1) v2HomeData := filepath.Join(homedir, "hello/20") l, err = filepath.Glob(filepath.Join(v2HomeData, "*")) c.Assert(err, IsNil) c.Assert(l, HasLen, 1) err = s.be.UndoCopySnapData(v2, v1, &s.nullProgress) c.Assert(err, IsNil) // now removed _, err = os.Stat(v2data) c.Assert(os.IsNotExist(err), Equals, true) _, err = os.Stat(v2HomeData) c.Assert(os.IsNotExist(err), Equals, true) }
func (s *assertMgrSuite) TestValidateRefreshesMissingValidation(c *C) { s.state.Lock() defer s.state.Unlock() snapDeclFoo := s.snapDecl(c, "foo", nil) snapDeclBar := s.snapDecl(c, "bar", []interface{}{"foo-id"}) s.stateFromDecl(snapDeclFoo, snap.R(7)) s.stateFromDecl(snapDeclBar, snap.R(3)) err := assertstate.Add(s.state, s.storeSigning.StoreAccountKey("")) c.Assert(err, IsNil) err = assertstate.Add(s.state, s.dev1Acct) c.Assert(err, IsNil) err = assertstate.Add(s.state, snapDeclFoo) c.Assert(err, IsNil) err = assertstate.Add(s.state, snapDeclBar) c.Assert(err, IsNil) fooRefresh := &snap.Info{ SideInfo: snap.SideInfo{RealName: "foo", SnapID: "foo-id", Revision: snap.R(9)}, } validated, err := assertstate.ValidateRefreshes(s.state, []*snap.Info{fooRefresh}, 0) c.Assert(err, ErrorMatches, `cannot refresh "foo" to revision 9: no validation by "bar"`) c.Check(validated, HasLen, 0) }
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 *hookManagerSuite) TestHookSetupJsonUnmarshal(c *C) { out, err := json.Marshal(HookSetup{Snap: "snap-name", Revision: snap.R(1), Hook: "hook-name"}) c.Assert(err, IsNil) var setup HookSetup err = json.Unmarshal(out, &setup) c.Assert(err, IsNil) c.Check(setup.Snap, Equals, "snap-name") c.Check(setup.Revision, Equals, snap.R(1)) c.Check(setup.Hook, Equals, "hook-name") }
func (s *patch2Suite) TestPatch2(c *C) { restorer := patch.MockLevel(2) defer restorer() r, err := os.Open(dirs.SnapStateFile) c.Assert(err, IsNil) defer r.Close() st, err := state.ReadState(nil, r) c.Assert(err, IsNil) // go from patch level 1 -> 2 err = patch.Apply(st) c.Assert(err, IsNil) st.Lock() defer st.Unlock() // our mocks are correct c.Assert(st.Changes(), HasLen, 2) c.Assert(st.Tasks(), HasLen, 2) var snapsup snapstate.SnapSetup // transition of: // - SnapSetup.{Name,Revision} -> SnapSetup.SideInfo.{RealName,Revision} t := st.Task("1") err = t.Get("snap-setup", &snapsup) c.Assert(err, IsNil) c.Assert(snapsup.SideInfo, DeepEquals, &snap.SideInfo{ RealName: "foo", Revision: snap.R("x3"), }) // transition of: // - SnapState.Sequence is backfilled with "RealName" (if missing) var snapst snapstate.SnapState err = snapstate.Get(st, "foo", &snapst) c.Assert(err, IsNil) c.Check(snapst.Sequence[0].RealName, Equals, "foo") c.Check(snapst.Sequence[1].RealName, Equals, "foo") // transition of: // - Candidate for "bar" -> tasks SnapSetup.SideInfo t = st.Task("2") err = t.Get("snap-setup", &snapsup) c.Assert(err, IsNil) c.Assert(snapsup.SideInfo, DeepEquals, &snap.SideInfo{ RealName: "bar", Revision: snap.R("x1"), }) // FIXME: bar is now empty and should no longer be there? err = snapstate.Get(st, "bar", &snapst) c.Assert(err, IsNil) }
func (s *copydataSuite) TestCopyData(c *C) { homedir := filepath.Join(s.tempdir, "home", "user1", "snap") homeData := filepath.Join(homedir, "hello/10") err := os.MkdirAll(homeData, 0755) c.Assert(err, IsNil) homeCommonData := filepath.Join(homedir, "hello/common") err = os.MkdirAll(homeCommonData, 0755) c.Assert(err, IsNil) canaryData := []byte("ni ni ni") v1 := snaptest.MockSnap(c, helloYaml1, helloContents, &snap.SideInfo{Revision: snap.R(10)}) // just creates data dirs in this case err = s.be.CopySnapData(v1, nil, &s.nullProgress) c.Assert(err, IsNil) canaryDataFile := filepath.Join(v1.DataDir(), "canary.txt") err = ioutil.WriteFile(canaryDataFile, canaryData, 0644) c.Assert(err, IsNil) canaryDataFile = filepath.Join(v1.CommonDataDir(), "canary.common") err = ioutil.WriteFile(canaryDataFile, canaryData, 0644) c.Assert(err, IsNil) err = ioutil.WriteFile(filepath.Join(homeData, "canary.home"), canaryData, 0644) c.Assert(err, IsNil) err = ioutil.WriteFile(filepath.Join(homeCommonData, "canary.common_home"), canaryData, 0644) c.Assert(err, IsNil) v2 := snaptest.MockSnap(c, helloYaml2, helloContents, &snap.SideInfo{Revision: snap.R(20)}) err = s.be.CopySnapData(v2, v1, &s.nullProgress) c.Assert(err, IsNil) newCanaryDataFile := filepath.Join(dirs.SnapDataDir, "hello/20", "canary.txt") content, err := ioutil.ReadFile(newCanaryDataFile) c.Assert(err, IsNil) c.Assert(content, DeepEquals, canaryData) // ensure common data file is still there (even though it didn't get copied) newCanaryDataFile = filepath.Join(dirs.SnapDataDir, "hello", "common", "canary.common") content, err = ioutil.ReadFile(newCanaryDataFile) c.Assert(err, IsNil) c.Assert(content, DeepEquals, canaryData) newCanaryDataFile = filepath.Join(homedir, "hello/20", "canary.home") content, err = ioutil.ReadFile(newCanaryDataFile) c.Assert(err, IsNil) c.Assert(content, DeepEquals, canaryData) // ensure home common data file is still there (even though it didn't get copied) newCanaryDataFile = filepath.Join(homedir, "hello", "common", "canary.common_home") content, err = ioutil.ReadFile(newCanaryDataFile) c.Assert(err, IsNil) c.Assert(content, DeepEquals, canaryData) }
func (s *copydataSuite) TestCopyDataBails(c *C) { oldSnapDataHomeGlob := dirs.SnapDataHomeGlob defer func() { dirs.SnapDataHomeGlob = oldSnapDataHomeGlob }() v1 := snaptest.MockSnap(c, helloYaml1, helloContents, &snap.SideInfo{Revision: snap.R(10)}) c.Assert(s.be.CopySnapData(v1, nil, &s.nullProgress), IsNil) c.Assert(os.Chmod(v1.DataDir(), 0), IsNil) v2 := snaptest.MockSnap(c, helloYaml2, helloContents, &snap.SideInfo{Revision: snap.R(20)}) err := s.be.CopySnapData(v2, v1, &s.nullProgress) c.Check(err, ErrorMatches, "cannot copy .*") }
func (s *revisionSuite) TestR(c *C) { type testItem struct { v interface{} n int e string } var tests = []testItem{{ v: 0, n: 0, }, { v: -1, n: -1, }, { v: 1, n: 1, }, { v: "unset", n: 0, }, { v: "x1", n: -1, }, { v: "1", n: 1, }, { v: "x-1", e: `invalid snap revision: "x-1"`, }, { v: "x0", e: `invalid snap revision: "x0"`, }, { v: "-1", e: `invalid snap revision: "-1"`, }, { v: "0", e: `invalid snap revision: "0"`, }, { v: int64(1), e: `cannot use 1 \(int64\) as a snap revision`, }} for _, test := range tests { if test.e != "" { f := func() { snap.R(test.v) } c.Assert(f, PanicMatches, test.e) continue } c.Assert(snap.R(test.v), Equals, snap.R(test.n)) } }
func (s *snapTestSuite) TestMockInfo(c *C) { snapInfo := snaptest.MockInfo(c, sampleYaml, &snap.SideInfo{Revision: snap.R(42)}) // Data from YAML is used c.Check(snapInfo.Name(), Equals, "sample") // Data from SideInfo is used c.Check(snapInfo.Revision, Equals, snap.R(42)) // The YAML is *not* placed on disk _, err := os.Stat(filepath.Join(dirs.SnapMountDir, "sample", "42", "meta", "snap.yaml")) c.Assert(os.IsNotExist(err), Equals, true) // More c.Check(snapInfo.Apps["app"].Command, Equals, "foo") c.Check(snapInfo.Plugs["network"].Interface, Equals, "network") }
func (s *setupSuite) TestSetupUndoIdempotent(c *C) { // make sure that a retry wouldn't stumble on partial work // use a kernel because that does and need to do strictly more // this cannot check systemd own behavior though around mounts! bootloader := boottest.NewMockBootloader("mock", c.MkDir()) partition.ForceBootloader(bootloader) // we don't get real mounting os.Setenv("SNAPPY_SQUASHFS_UNPACK_FOR_TESTS", "1") defer os.Unsetenv("SNAPPY_SQUASHFS_UNPACK_FOR_TESTS") testFiles := [][]string{ {"kernel.img", "kernel"}, {"initrd.img", "initrd"}, {"modules/4.4.0-14-generic/foo.ko", "a module"}, {"firmware/bar.bin", "some firmware"}, {"meta/kernel.yaml", "version: 4.2"}, } snapPath := snaptest.MakeTestSnapWithFiles(c, `name: kernel version: 1.0 type: kernel `, testFiles) si := snap.SideInfo{ RealName: "kernel", Revision: snap.R(140), } err := s.be.SetupSnap(snapPath, &si, &s.nullProgress) c.Assert(err, IsNil) minInfo := snap.MinimalPlaceInfo("kernel", snap.R(140)) err = s.be.UndoSetupSnap(minInfo, "kernel", &s.nullProgress) c.Assert(err, IsNil) // retry run err = s.be.UndoSetupSnap(minInfo, "kernel", &s.nullProgress) c.Assert(err, IsNil) // sanity checks l, _ := filepath.Glob(filepath.Join(dirs.SnapServicesDir, "*.mount")) c.Assert(l, HasLen, 0) c.Assert(osutil.FileExists(minInfo.MountDir()), Equals, false) c.Assert(osutil.FileExists(minInfo.MountFile()), Equals, false) l, _ = filepath.Glob(filepath.Join(bootloader.Dir(), "*")) c.Assert(l, HasLen, 0) }
func (s *kernelOSSuite) TestInUse(c *C) { for _, t := range []struct { bootVarKey string bootVarValue string snapName string snapRev snap.Revision inUse bool }{ // in use {"snap_kernel", "kernel_41.snap", "kernel", snap.R(41), true}, {"snap_try_kernel", "kernel_82.snap", "kernel", snap.R(82), true}, {"snap_core", "core_21.snap", "core", snap.R(21), true}, {"snap_try_core", "core_42.snap", "core", snap.R(42), true}, // not in use {"snap_core", "core_111.snap", "core", snap.R(21), false}, {"snap_try_core", "core_111.snap", "core", snap.R(21), false}, {"snap_kernel", "kernel_111.snap", "kernel", snap.R(1), false}, {"snap_try_kernel", "kernel_111.snap", "kernel", snap.R(1), false}, } { s.bootloader.BootVars[t.bootVarKey] = t.bootVarValue c.Assert(boot.InUse(t.snapName, t.snapRev), Equals, t.inUse, Commentf("unexpected result: %s %s %v", t.snapName, t.snapRev, t.inUse)) } }
func (s *hookManagerSuite) TestRunHookInstruction(c *C) { s.state.Lock() defer s.state.Unlock() task := HookTask(s.state, "test summary", "test-snap", snap.R(1), "test-hook") c.Assert(task, NotNil, Commentf("Expected HookTask to return a task")) c.Check(task.Kind(), Equals, "run-hook") var setup HookSetup err := task.Get("hook-setup", &setup) c.Check(err, IsNil, Commentf("Expected task to contain hook setup")) c.Check(setup.Snap, Equals, "test-snap") c.Check(setup.Revision, Equals, snap.R(1)) c.Check(setup.Hook, Equals, "test-hook") }
func (s *downloadSnapSuite) TestDoDownloadSnapCompatbility(c *C) { s.state.Lock() t := s.state.NewTask("download-snap", "test") t.Set("snap-setup", &snapstate.SnapSetup{ SideInfo: &snap.SideInfo{ RealName: "foo", }, Channel: "some-channel", // explicitly set to "nil", this ensures the compatibility // code path in the task is hit and the store is queried // in the task (instead of using the new // SnapSetup.{SideInfo,DownloadInfo} that gets set in // snapstate.{Install,Update} directely. DownloadInfo: nil, }) s.state.NewChange("dummy", "...").AddTask(t) s.state.Unlock() s.snapmgr.Ensure() s.snapmgr.Wait() // the compat code called the store "Snap" endpoint c.Assert(s.fakeBackend.ops, DeepEquals, fakeOps{ { op: "storesvc-snap", name: "foo", revno: snap.R(11), }, { op: "storesvc-download", name: "foo", }, }) s.state.Lock() defer s.state.Unlock() var ss snapstate.SnapSetup t.Get("snap-setup", &ss) c.Check(ss.SideInfo, DeepEquals, &snap.SideInfo{ RealName: "foo", SnapID: "snapIDsnapidsnapidsnapidsnapidsn", Revision: snap.R(11), Channel: "some-channel", }) c.Check(t.Status(), Equals, state.DoneStatus) }