Example #1
0
func (s *snapmgrTestSuite) TestUpdateResetAliasesChangeConflict(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.Update(s.state, "some-snap", "some-channel", snap.R(0), s.user.ID, snapstate.Flags{})
	c.Assert(err, IsNil)
	// need a change to make the tasks visible
	s.state.NewChange("update", "...").AddAll(ts)

	_, err = snapstate.ResetAliases(s.state, "some-snap", []string{"alias1"})
	c.Assert(err, ErrorMatches, `snap "some-snap" has changes in progress`)
}
Example #2
0
func (s *snapmgrTestSuite) TestAliasMatrixTotalUndoRunThrough(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,
	})

	// alias1 is a non auto-alias
	// alias5 is an auto-alias
	// alias1lost is a non auto-alias and doesn't have an entry in the snap anymore
	// alias5lost is an auto-alias and doesn't have an entry in the snap any
	snapstate.AutoAliases = func(st *state.State, info *snap.Info) ([]string, error) {
		c.Check(info.Name(), Equals, "alias-snap")
		return []string{"alias5", "alias5lost"}, nil
	}
	cmds := map[string]string{
		"alias1": "cmd1",
		"alias5": "cmd5",
	}

	defer s.snapmgr.Stop()
	for _, scenario := range statusesMatrix {
		scenAlias := scenario.alias
		if scenario.beforeStatus != "" {
			s.state.Set("aliases", map[string]map[string]string{
				"alias-snap": {
					scenAlias: scenario.beforeStatus,
				},
			})
		} else {
			s.state.Set("aliases", nil)
		}

		chg := s.state.NewChange("scenario", "...")
		var err error
		var ts *state.TaskSet
		targets := []string{scenAlias}

		switch scenario.action {
		case "alias":
			ts, err = snapstate.Alias(s.state, "alias-snap", targets)
		case "unalias":
			ts, err = snapstate.Unalias(s.state, "alias-snap", targets)
		case "reset":
			ts, err = snapstate.ResetAliases(s.state, "alias-snap", targets)
		}
		c.Assert(err, IsNil)

		chg.AddAll(ts)

		tasks := ts.Tasks()
		last := tasks[len(tasks)-1]

		terr := s.state.NewTask("error-trigger", "provoking total undo")
		terr.WaitFor(last)
		chg.AddTask(terr)

		s.state.Unlock()
		for i := 0; i < 3; i++ {
			s.snapmgr.Ensure()
			s.snapmgr.Wait()
		}
		s.state.Lock()

		c.Assert(chg.Status(), Equals, state.ErrorStatus, Commentf("%#v: %v", scenario, chg.Err()))
		var aliases []*backend.Alias
		var rmAliases []*backend.Alias
		beAlias := &backend.Alias{scenAlias, fmt.Sprintf("alias-snap.%s", cmds[scenAlias])}
		switch scenario.mutation {
		case "-":
		case "add":
			aliases = []*backend.Alias{beAlias}
		case "rm":
			rmAliases = []*backend.Alias{beAlias}
		}

		comm := Commentf("%#v", scenario)
		expected := fakeOps{
			{
				op:        "update-aliases",
				aliases:   aliases,
				rmAliases: rmAliases,
			},
			{
				op:      "matching-aliases",
				aliases: aliases,
			},
			{
				op:      "missing-aliases",
				aliases: rmAliases,
			},
			{
				op:        "update-aliases",
				aliases:   rmAliases,
				rmAliases: aliases,
			},
		}
		// start with an easier-to-read error if this fails:
		c.Assert(s.fakeBackend.ops.Ops(), DeepEquals, expected.Ops(), comm)
		c.Assert(s.fakeBackend.ops, DeepEquals, expected, comm)

		var allAliases map[string]map[string]string
		err = s.state.Get("aliases", &allAliases)
		c.Assert(err, IsNil)
		if scenario.beforeStatus != "" {
			c.Check(allAliases, DeepEquals, map[string]map[string]string{
				"alias-snap": {scenAlias: scenario.beforeStatus},
			}, comm)
		} else {
			c.Check(allAliases, HasLen, 0, comm)
		}

		s.fakeBackend.ops = nil
	}
}