func (ss *stateSuite) TestCheckpointPreserveLastIds(c *C) { b := new(fakeStateBackend) st := state.New(b) st.Lock() st.NewChange("install", "...") st.NewTask("download", "...") st.NewTask("download", "...") // implicit checkpoint st.Unlock() c.Assert(b.checkpoints, HasLen, 1) buf := bytes.NewBuffer(b.checkpoints[0]) st2, err := state.ReadState(nil, buf) c.Assert(err, IsNil) st2.Lock() defer st2.Unlock() c.Assert(st2.NewTask("download", "...").ID(), Equals, "3") c.Assert(st2.NewChange("install", "...").ID(), Equals, "2") }
func (ts *taskSuite) TestProgressDefaults(c *C) { st := state.New(nil) st.Lock() defer st.Unlock() t := st.NewTask("download", "1...") c.Check(t.Status(), Equals, state.DoStatus) cur, tot := t.Progress() c.Check(cur, Equals, 0) c.Check(tot, Equals, 1) t.SetStatus(state.DoStatus) cur, tot = t.Progress() c.Check(cur, Equals, 0) c.Check(tot, Equals, 1) t.SetStatus(state.DoneStatus) cur, tot = t.Progress() c.Check(cur, Equals, 1) c.Check(tot, Equals, 1) t.SetStatus(state.ErrorStatus) cur, tot = t.Progress() c.Check(cur, Equals, 1) c.Check(tot, Equals, 1) }
func (ss *stateSuite) TestNewTaskAndTasks(c *C) { st := state.New(nil) st.Lock() defer st.Unlock() chg1 := st.NewChange("install", "...") t11 := st.NewTask("check", "...") chg1.AddTask(t11) t12 := st.NewTask("inst", "...") chg1.AddTask(t12) chg2 := st.NewChange("remove", "...") t21 := st.NewTask("check", "...") t22 := st.NewTask("rm", "...") chg2.AddTask(t22) tasks := st.Tasks() c.Check(tasks, HasLen, 4) expected := map[string]*state.Task{ t11.ID(): t11, t12.ID(): t12, t21.ID(): t21, t22.ID(): t22, } for _, t := range tasks { c.Check(t, Equals, expected[t.ID()]) } }
func (cs *changeSuite) TestAbort(c *C) { st := state.New(nil) st.Lock() defer st.Unlock() chg := st.NewChange("install", "...") for s := state.DefaultStatus + 1; s < state.ErrorStatus+1; s++ { t := st.NewTask("download", s.String()) t.SetStatus(s) t.Set("old-status", s) chg.AddTask(t) } chg.Abort() tasks := chg.Tasks() for _, t := range tasks { var s state.Status err := t.Get("old-status", &s) c.Assert(err, IsNil) c.Logf("Checking %s task after abort", t.Summary()) switch s { case state.DoStatus: c.Assert(t.Status(), Equals, state.HoldStatus) case state.DoneStatus: c.Assert(t.Status(), Equals, state.UndoStatus) case state.DoingStatus: c.Assert(t.Status(), Equals, state.AbortStatus) default: c.Assert(t.Status(), Equals, s) } } }
func (ts *taskRunnerSuite) TestExternalAbort(c *C) { sb := &stateBackend{} st := state.New(sb) r := state.NewTaskRunner(st) defer r.Stop() ch := make(chan bool) r.AddHandler("blocking", func(t *state.Task, tb *tomb.Tomb) error { ch <- true <-tb.Dying() return nil }, nil) st.Lock() chg := st.NewChange("install", "...") t := st.NewTask("blocking", "...") chg.AddTask(t) st.Unlock() r.Ensure() <-ch st.Lock() chg.Abort() st.Unlock() // The Abort above must make Ensure kill the task, or this will never end. ensureChange(c, r, sb, chg) }
func (cs *changeSuite) TestErr(c *C) { st := state.New(nil) st.Lock() defer st.Unlock() chg := st.NewChange("install", "...") t1 := st.NewTask("download", "Download") t2 := st.NewTask("activate", "Activate") chg.AddTask(t1) chg.AddTask(t2) c.Assert(chg.Err(), IsNil) // t2 still running so change not yet in ErrorStatus t1.SetStatus(state.ErrorStatus) c.Assert(chg.Err(), IsNil) t2.SetStatus(state.ErrorStatus) c.Assert(chg.Err(), ErrorMatches, `internal inconsistency: change "install" in ErrorStatus with no task errors logged`) t1.Errorf("Download error") c.Assert(chg.Err(), ErrorMatches, ""+ "cannot perform the following tasks:\n"+ "- Download \\(Download error\\)") t2.Errorf("Activate error") c.Assert(chg.Err(), ErrorMatches, ""+ "cannot perform the following tasks:\n"+ "- Download \\(Download error\\)\n"+ "- Activate \\(Activate error\\)") }
func (cs *changeSuite) TestCloseReadyWhenTasksReady(c *C) { st := state.New(nil) st.Lock() defer st.Unlock() chg := st.NewChange("install", "...") t1 := st.NewTask("download", "...") t2 := st.NewTask("download", "...") chg.AddTask(t1) chg.AddTask(t2) select { case <-chg.Ready(): c.Fatalf("Change should not be ready") default: } t1.SetStatus(state.DoneStatus) select { case <-chg.Ready(): c.Fatalf("Change should not be ready") default: } t2.SetStatus(state.DoneStatus) select { case <-chg.Ready(): default: c.Fatalf("Change should be ready") } }
func populateStateFromInstalled() error { all, err := (&snappy.Overlord{}).Installed() if err != nil { return err } if osutil.FileExists(dirs.SnapStateFile) { return fmt.Errorf("cannot create state: state %q already exists", dirs.SnapStateFile) } st := state.New(&overlordStateBackend{ path: dirs.SnapStateFile, }) st.Lock() defer st.Unlock() for _, sn := range all { // no need to do a snapstate.Get() because this is firstboot info := sn.Info() var snapst snapstate.SnapState snapst.Sequence = append(snapst.Sequence, &info.SideInfo) snapst.Channel = info.Channel snapst.Active = sn.IsActive() snapstate.Set(st, sn.Name(), &snapst) } return nil }
func (ts *taskSuite) TestState(c *C) { st := state.New(nil) st.Lock() t := st.NewTask("download", "1...") st.Unlock() c.Assert(t.State(), Equals, st) }
func (ss *stateSuite) TestEnsureBefore(c *C) { b := new(fakeStateBackend) st := state.New(b) st.EnsureBefore(10 * time.Second) c.Check(b.ensureBefore, Equals, 10*time.Second) }
func (ams *assertMgrSuite) TestManagerAndDB(c *C) { s := state.New(nil) mgr, err := assertstate.Manager(s) c.Assert(err, IsNil) db := mgr.DB() c.Check(db, FitsTypeOf, (*asserts.Database)(nil)) }
func (cs *changeSuite) TestState(c *C) { st := state.New(nil) st.Lock() chg := st.NewChange("install", "...") st.Unlock() c.Assert(chg.State(), Equals, st) }
func (ss *stateSuite) TestGetNoState(c *C) { st := state.New(nil) st.Lock() defer st.Unlock() var mSt1B mgrState1 err := st.Get("mgr9", &mSt1B) c.Check(err, Equals, state.ErrNoState) }
func (cs *changeSuite) TestNewChange(c *C) { st := state.New(nil) st.Lock() defer st.Unlock() chg := st.NewChange("install", "summary...") c.Check(chg.Kind(), Equals, "install") c.Check(chg.Summary(), Equals, "summary...") }
func (s *interfaceManagerSuite) SetUpTest(c *C) { dirs.SetRootDir(c.MkDir()) state := state.New(nil) s.state = state s.privateMgr = nil s.extraIfaces = nil s.secBackend = &interfaces.TestSecurityBackend{} s.restoreBackends = ifacestate.MockSecurityBackends([]interfaces.SecurityBackend{s.secBackend}) }
func (cs *taskSuite) TestErrorf(c *C) { st := state.New(nil) st.Lock() defer st.Unlock() t := st.NewTask("download", "1...") t.Errorf("Some %s", "error") c.Assert(t.Log()[0], Matches, "....-..-..T.* ERROR Some error") }
func (ts *taskSuite) TestNewTask(c *C) { st := state.New(nil) st.Lock() defer st.Unlock() t := st.NewTask("download", "1...") c.Check(t.Kind(), Equals, "download") c.Check(t.Summary(), Equals, "1...") }
func (ss *stateSuite) TestSetPanic(c *C) { st := state.New(nil) st.Lock() defer st.Unlock() unsupported := struct { Ch chan bool }{} c.Check(func() { st.Set("mgr9", unsupported) }, PanicMatches, `internal error: could not marshal value for state entry "mgr9": json: unsupported type:.*`) }
func (ts *taskSuite) TestTaskWaitFor(c *C) { st := state.New(nil) st.Lock() defer st.Unlock() t1 := st.NewTask("download", "1...") t2 := st.NewTask("install", "2...") t2.WaitFor(t1) c.Assert(t2.WaitTasks(), DeepEquals, []*state.Task{t1}) c.Assert(t1.HaltTasks(), DeepEquals, []*state.Task{t2}) }
func (ss *stateSuite) TestPrune(c *C) { st := state.New(&fakeStateBackend{}) st.Lock() defer st.Unlock() now := time.Now() pruneWait := 1 * time.Hour abortWait := 3 * time.Hour unset := time.Time{} t1 := st.NewTask("foo", "...") t2 := st.NewTask("foo", "...") t3 := st.NewTask("foo", "...") t4 := st.NewTask("foo", "...") chg1 := st.NewChange("abort", "...") chg1.AddTask(t1) state.MockChangeTimes(chg1, now.Add(-abortWait), unset) chg2 := st.NewChange("prune", "...") chg2.AddTask(t2) c.Assert(chg2.Status(), Equals, state.DoStatus) state.MockChangeTimes(chg2, now.Add(-pruneWait), now.Add(-pruneWait)) chg3 := st.NewChange("ready-but-recent", "...") chg3.AddTask(t3) state.MockChangeTimes(chg3, now.Add(-pruneWait), now.Add(-pruneWait/2)) chg4 := st.NewChange("old-but-not-ready", "...") chg4.AddTask(t4) state.MockChangeTimes(chg4, now.Add(-pruneWait/2), unset) st.Prune(pruneWait, abortWait) c.Assert(st.Change(chg1.ID()), Equals, chg1) c.Assert(st.Change(chg2.ID()), IsNil) c.Assert(st.Change(chg3.ID()), Equals, chg3) c.Assert(st.Change(chg4.ID()), Equals, chg4) c.Assert(st.Task(t1.ID()), Equals, t1) c.Assert(st.Task(t2.ID()), IsNil) c.Assert(st.Task(t3.ID()), Equals, t3) c.Assert(st.Task(t4.ID()), Equals, t4) c.Assert(chg1.Status(), Equals, state.HoldStatus) c.Assert(chg3.Status(), Equals, state.DoStatus) c.Assert(chg4.Status(), Equals, state.DoStatus) c.Assert(t1.Status(), Equals, state.HoldStatus) c.Assert(t3.Status(), Equals, state.DoStatus) c.Assert(t4.Status(), Equals, state.DoStatus) }
func loadState(backend state.Backend) (*state.State, error) { if !osutil.FileExists(dirs.SnapStateFile) { return state.New(backend), nil } r, err := os.Open(dirs.SnapStateFile) if err != nil { return nil, fmt.Errorf("failed to read the state file: %s", err) } defer r.Close() return state.ReadState(backend, r) }
func (ts *taskSuite) TestStatusAndSetStatus(c *C) { st := state.New(nil) st.Lock() defer st.Unlock() t := st.NewTask("download", "1...") c.Check(t.Status(), Equals, state.DoStatus) t.SetStatus(state.DoneStatus) c.Check(t.Status(), Equals, state.DoneStatus) }
func (cs *taskSuite) TestNewTaskSet(c *C) { ts0 := state.NewTaskSet() c.Check(ts0.Tasks(), HasLen, 0) st := state.New(nil) st.Lock() t1 := st.NewTask("download", "1...") t2 := st.NewTask("install", "2...") ts2 := state.NewTaskSet(t1, t2) st.Unlock() c.Assert(ts2.Tasks(), DeepEquals, []*state.Task{t1, t2}) }
func (ts *taskSuite) TestTaskMarshalsLog(c *C) { st := state.New(nil) st.Lock() defer st.Unlock() t := st.NewTask("download", "1...") t.Logf("foo") d, err := t.MarshalJSON() c.Assert(err, IsNil) c.Assert(string(d), Matches, `.*"log":\["....-..-..T.* INFO foo"\].*`) }
func (ss *stateSuite) TestNewChangeAndCheckpoint(c *C) { b := new(fakeStateBackend) st := state.New(b) st.Lock() chg := st.NewChange("install", "summary") c.Assert(chg, NotNil) chgID := chg.ID() chg.Set("a", 1) chg.SetStatus(state.ErrorStatus) spawnTime := chg.SpawnTime() readyTime := chg.ReadyTime() // implicit checkpoint st.Unlock() c.Assert(b.checkpoints, HasLen, 1) buf := bytes.NewBuffer(b.checkpoints[0]) st2, err := state.ReadState(nil, buf) c.Assert(err, IsNil) c.Assert(st2, NotNil) st2.Lock() defer st2.Unlock() chgs := st2.Changes() c.Assert(chgs, HasLen, 1) chg0 := chgs[0] c.Check(chg0.ID(), Equals, chgID) c.Check(chg0.Kind(), Equals, "install") c.Check(chg0.Summary(), Equals, "summary") c.Check(chg0.SpawnTime().Equal(spawnTime), Equals, true) c.Check(chg0.ReadyTime().Equal(readyTime), Equals, true) var v int err = chg0.Get("a", &v) c.Check(v, Equals, 1) c.Check(chg0.Status(), Equals, state.ErrorStatus) select { case <-chg0.Ready(): default: c.Errorf("Change didn't preserve Ready channel closed after deserialization") } }
func (s *progressAdapterTestSuite) TestProgressAdapterWrite(c *C) { st := state.New(nil) st.Lock() p := TaskProgressAdapter{ task: st.NewTask("op", "msg"), } st.Unlock() p.Start("msg", 161803) c.Check(p.total, Equals, float64(161803)) p.Write([]byte("some-bytes")) c.Check(p.current, Equals, float64(len("some-bytes"))) }
func (cs *changeSuite) TestGetSet(c *C) { st := state.New(nil) st.Lock() defer st.Unlock() chg := st.NewChange("install", "...") chg.Set("a", 1) var v int err := chg.Get("a", &v) c.Assert(err, IsNil) c.Check(v, Equals, 1) }
func (ts *taskSuite) TestGetSet(c *C) { st := state.New(nil) st.Lock() defer st.Unlock() t := st.NewTask("download", "1...") t.Set("a", 1) var v int err := t.Get("a", &v) c.Assert(err, IsNil) c.Check(v, Equals, 1) }
func (ts *taskSuite) TestTaskWaitAll(c *C) { st := state.New(nil) st.Lock() defer st.Unlock() t1 := st.NewTask("download", "1...") t2 := st.NewTask("install", "2...") t3 := st.NewTask("setup", "3...") t3.WaitAll(state.NewTaskSet(t1, t2)) c.Assert(t3.WaitTasks(), HasLen, 2) c.Assert(t1.HaltTasks(), DeepEquals, []*state.Task{t3}) c.Assert(t2.HaltTasks(), DeepEquals, []*state.Task{t3}) }
func (ss *stateSuite) TestGetUnmarshalProblem(c *C) { st := state.New(nil) st.Lock() defer st.Unlock() mismatched := struct { A int }{A: 22} st.Set("mgr9", &mismatched) var mSt1B mgrState1 err := st.Get("mgr9", &mSt1B) c.Check(err, ErrorMatches, `internal error: could not unmarshal state entry "mgr9": json: cannot unmarshal .*`) }