func change2changeInfo(chg *state.Change) *changeInfo { status := chg.Status() chgInfo := &changeInfo{ ID: chg.ID(), Kind: chg.Kind(), Summary: chg.Summary(), Status: status.String(), Ready: status.Ready(), SpawnTime: chg.SpawnTime(), } readyTime := chg.ReadyTime() if !readyTime.IsZero() { chgInfo.ReadyTime = &readyTime } if err := chg.Err(); err != nil { chgInfo.Err = err.Error() } tasks := chg.Tasks() taskInfos := make([]*taskInfo, len(tasks)) for j, t := range tasks { label, done, total := t.Progress() taskInfo := &taskInfo{ ID: t.ID(), Kind: t.Kind(), Summary: t.Summary(), Status: t.Status().String(), Log: t.Log(), Progress: taskInfoProgress{ Label: label, Done: done, Total: total, }, SpawnTime: t.SpawnTime(), } readyTime := t.ReadyTime() if !readyTime.IsZero() { taskInfo.ReadyTime = &readyTime } taskInfos[j] = taskInfo } chgInfo.Tasks = taskInfos var data map[string]*json.RawMessage if chg.Get("api-data", &data) == nil { chgInfo.Data = data } return chgInfo }
func ensureChange(c *C, r *state.TaskRunner, sb *stateBackend, chg *state.Change) { for i := 0; i < 10; i++ { sb.ensureBefore = time.Hour r.Ensure() r.Wait() chg.State().Lock() s := chg.Status() chg.State().Unlock() if s.Ready() { return } if sb.ensureBefore > 0 { break } } var statuses []string chg.State().Lock() for _, t := range chg.Tasks() { statuses = append(statuses, t.Summary()+":"+t.Status().String()) } chg.State().Unlock() c.Fatalf("Change didn't reach final state without blocking: %s", strings.Join(statuses, " ")) }