Merge pull request #4071 from hashicorp/b-handle-missing-finishedat

handle missing finishedAt
This commit is contained in:
Preetha 2018-03-29 17:11:34 -05:00 committed by GitHub
commit 9a732c4acb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 52 additions and 15 deletions

View file

@ -5730,16 +5730,30 @@ func (a *Allocation) RescheduleEligible(reschedulePolicy *ReschedulePolicy, fail
}
// LastEventTime is the time of the last task event in the allocation.
// It is used to determine allocation failure time.
// It is used to determine allocation failure time. If the FinishedAt field
// is not set, the alloc's modify time is used
func (a *Allocation) LastEventTime() time.Time {
var lastEventTime time.Time
if a.TaskStates != nil {
for _, e := range a.TaskStates {
if lastEventTime.IsZero() || e.FinishedAt.After(lastEventTime) {
lastEventTime = e.FinishedAt
for _, s := range a.TaskStates {
if lastEventTime.IsZero() || s.FinishedAt.After(lastEventTime) {
lastEventTime = s.FinishedAt
}
}
}
// If no tasks have FinsihedAt set, examine task events
if lastEventTime.IsZero() {
for _, s := range a.TaskStates {
for _, e := range s.Events {
if lastEventTime.IsZero() || e.Time > lastEventTime.UnixNano() {
lastEventTime = time.Unix(0, e.Time).UTC()
}
}
}
}
if lastEventTime.IsZero() {
return time.Unix(0, a.ModifyTime).UTC()
}
return lastEventTime
}

View file

@ -2655,35 +2655,34 @@ func TestAllocation_LastEventTime(t *testing.T) {
taskState map[string]*TaskState
expectedLastEventTime time.Time
}
var timeZero time.Time
t1 := time.Now()
t1 := time.Now().UTC()
testCases := []testCase{
{
desc: "nil task state",
expectedLastEventTime: timeZero,
expectedLastEventTime: t1,
},
{
desc: "empty task state",
taskState: make(map[string]*TaskState),
expectedLastEventTime: timeZero,
expectedLastEventTime: t1,
},
{
desc: "Finished At not set",
taskState: map[string]*TaskState{"foo": {State: "start",
StartedAt: t1.Add(-2 * time.Hour)}},
expectedLastEventTime: timeZero,
expectedLastEventTime: t1,
},
{
desc: "One finished event",
desc: "One finished ",
taskState: map[string]*TaskState{"foo": {State: "start",
StartedAt: t1.Add(-2 * time.Hour),
FinishedAt: t1.Add(-1 * time.Hour)}},
expectedLastEventTime: t1.Add(-1 * time.Hour),
},
{
desc: "Multiple events",
desc: "Multiple task groups",
taskState: map[string]*TaskState{"foo": {State: "start",
StartedAt: t1.Add(-2 * time.Hour),
FinishedAt: t1.Add(-1 * time.Hour)},
@ -2692,10 +2691,33 @@ func TestAllocation_LastEventTime(t *testing.T) {
FinishedAt: t1.Add(-40 * time.Minute)}},
expectedLastEventTime: t1.Add(-40 * time.Minute),
},
{
desc: "No finishedAt set, one task event",
taskState: map[string]*TaskState{"foo": {
State: "run",
StartedAt: t1.Add(-2 * time.Hour),
Events: []*TaskEvent{
{Type: "start", Time: t1.Add(-20 * time.Minute).UnixNano()},
}},
},
expectedLastEventTime: t1.Add(-20 * time.Minute),
},
{
desc: "No finishedAt set, many task events",
taskState: map[string]*TaskState{"foo": {
State: "run",
StartedAt: t1.Add(-2 * time.Hour),
Events: []*TaskEvent{
{Type: "start", Time: t1.Add(-20 * time.Minute).UnixNano()},
{Type: "status change", Time: t1.Add(-10 * time.Minute).UnixNano()},
}},
},
expectedLastEventTime: t1.Add(-10 * time.Minute),
},
}
for _, tc := range testCases {
t.Run(tc.desc, func(t *testing.T) {
alloc := &Allocation{}
alloc := &Allocation{CreateTime: t1.UnixNano(), ModifyTime: t1.UnixNano()}
alloc.TaskStates = tc.taskState
require.Equal(t, tc.expectedLastEventTime, alloc.LastEventTime())
})
@ -2727,10 +2749,11 @@ func TestAllocation_NextDelay(t *testing.T) {
reschedulePolicy: &ReschedulePolicy{
DelayFunction: "constant",
Delay: 5 * time.Second,
Unlimited: true,
},
alloc: &Allocation{ClientStatus: AllocClientStatusFailed},
expectedRescheduleTime: time.Time{},
expectedRescheduleEligible: false,
alloc: &Allocation{ClientStatus: AllocClientStatusFailed, ModifyTime: now.UnixNano()},
expectedRescheduleTime: now.UTC().Add(5 * time.Second),
expectedRescheduleEligible: true,
},
{
desc: "linear delay, unlimited restarts, no reschedule tracker",