More alloc runner tests ported from 0.8.7
This commit is contained in:
parent
7c9b40a6f1
commit
43679f4ce1
|
@ -777,3 +777,168 @@ func TestAllocRunner_HandlesArtifactFailure(t *testing.T) {
|
|||
require.Equal(t, structs.TaskStateDead, state.TaskStates["bad"].State)
|
||||
require.True(t, state.TaskStates["bad"].Failed)
|
||||
}
|
||||
|
||||
// Test that alloc runner kills tasks in task group when another task fails
|
||||
func TestAllocRunner_TaskFailed_KillTG(t *testing.T) {
|
||||
alloc := mock.BatchAlloc()
|
||||
tr := alloc.AllocatedResources.Tasks[alloc.Job.TaskGroups[0].Tasks[0].Name]
|
||||
alloc.Job.TaskGroups[0].RestartPolicy.Attempts = 0
|
||||
|
||||
// Create two tasks in the task group
|
||||
task := alloc.Job.TaskGroups[0].Tasks[0]
|
||||
task.Name = "task1"
|
||||
task.Driver = "mock_driver"
|
||||
task.KillTimeout = 10 * time.Millisecond
|
||||
task.Config = map[string]interface{}{
|
||||
"run_for": "10s",
|
||||
}
|
||||
|
||||
task2 := alloc.Job.TaskGroups[0].Tasks[0].Copy()
|
||||
task2.Name = "task 2"
|
||||
task2.Driver = "mock_driver"
|
||||
task2.Config = map[string]interface{}{
|
||||
"start_error": "fail task please",
|
||||
}
|
||||
alloc.Job.TaskGroups[0].Tasks = append(alloc.Job.TaskGroups[0].Tasks, task2)
|
||||
alloc.AllocatedResources.Tasks[task.Name] = tr
|
||||
alloc.AllocatedResources.Tasks[task2.Name] = tr
|
||||
|
||||
conf, cleanup := testAllocRunnerConfig(t, alloc)
|
||||
defer cleanup()
|
||||
ar, err := NewAllocRunner(conf)
|
||||
require.NoError(t, err)
|
||||
defer destroy(ar)
|
||||
go ar.Run()
|
||||
upd := conf.StateUpdater.(*MockStateUpdater)
|
||||
|
||||
testutil.WaitForResult(func() (bool, error) {
|
||||
last := upd.Last()
|
||||
if last == nil {
|
||||
return false, fmt.Errorf("No updates")
|
||||
}
|
||||
if last.ClientStatus != structs.AllocClientStatusFailed {
|
||||
return false, fmt.Errorf("got status %v; want %v", last.ClientStatus, structs.AllocClientStatusFailed)
|
||||
}
|
||||
|
||||
// Task One should be killed
|
||||
state1 := last.TaskStates[task.Name]
|
||||
if state1.State != structs.TaskStateDead {
|
||||
return false, fmt.Errorf("got state %v; want %v", state1.State, structs.TaskStateDead)
|
||||
}
|
||||
if len(state1.Events) < 2 {
|
||||
// At least have a received and destroyed
|
||||
return false, fmt.Errorf("Unexpected number of events")
|
||||
}
|
||||
|
||||
found := false
|
||||
for _, e := range state1.Events {
|
||||
if e.Type != structs.TaskSiblingFailed {
|
||||
found = true
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
return false, fmt.Errorf("Did not find event %v", structs.TaskSiblingFailed)
|
||||
}
|
||||
|
||||
// Task Two should be failed
|
||||
state2 := last.TaskStates[task2.Name]
|
||||
if state2.State != structs.TaskStateDead {
|
||||
return false, fmt.Errorf("got state %v; want %v", state2.State, structs.TaskStateDead)
|
||||
}
|
||||
if !state2.Failed {
|
||||
return false, fmt.Errorf("task2 should have failed")
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}, func(err error) {
|
||||
require.Fail(t, "err: %v", err)
|
||||
})
|
||||
}
|
||||
|
||||
// Test that alloc becoming terminal should destroy the alloc runner
|
||||
func TestAllocRunner_TerminalUpdate_Destroy(t *testing.T) {
|
||||
t.Parallel()
|
||||
alloc := mock.BatchAlloc()
|
||||
tr := alloc.AllocatedResources.Tasks[alloc.Job.TaskGroups[0].Tasks[0].Name]
|
||||
alloc.Job.TaskGroups[0].RestartPolicy.Attempts = 0
|
||||
// Ensure task takes some time
|
||||
task := alloc.Job.TaskGroups[0].Tasks[0]
|
||||
task.Driver = "mock_driver"
|
||||
task.Config["run_for"] = "10s"
|
||||
alloc.AllocatedResources.Tasks[task.Name] = tr
|
||||
|
||||
conf, cleanup := testAllocRunnerConfig(t, alloc)
|
||||
defer cleanup()
|
||||
ar, err := NewAllocRunner(conf)
|
||||
require.NoError(t, err)
|
||||
defer destroy(ar)
|
||||
go ar.Run()
|
||||
upd := conf.StateUpdater.(*MockStateUpdater)
|
||||
|
||||
testutil.WaitForResult(func() (bool, error) {
|
||||
last := upd.Last()
|
||||
if last == nil {
|
||||
return false, fmt.Errorf("No updates")
|
||||
}
|
||||
if last.ClientStatus != structs.AllocClientStatusRunning {
|
||||
return false, fmt.Errorf("got status %v; want %v", last.ClientStatus, structs.AllocClientStatusRunning)
|
||||
}
|
||||
return true, nil
|
||||
}, func(err error) {
|
||||
require.Fail(t, "err: %v", err)
|
||||
})
|
||||
|
||||
// Update the alloc to be terminal which should cause the alloc runner to
|
||||
// stop the tasks and wait for a destroy.
|
||||
update := ar.alloc.Copy()
|
||||
update.DesiredStatus = structs.AllocDesiredStatusStop
|
||||
ar.Update(update)
|
||||
|
||||
testutil.WaitForResult(func() (bool, error) {
|
||||
last := upd.Last()
|
||||
if last == nil {
|
||||
return false, fmt.Errorf("No updates")
|
||||
}
|
||||
|
||||
// Check the status has changed.
|
||||
if last.ClientStatus != structs.AllocClientStatusComplete {
|
||||
return false, fmt.Errorf("got client status %v; want %v", last.ClientStatus, structs.AllocClientStatusComplete)
|
||||
}
|
||||
|
||||
// Check the alloc directory still exists
|
||||
if _, err := os.Stat(ar.allocDir.AllocDir); err != nil {
|
||||
return false, fmt.Errorf("alloc dir destroyed: %v", ar.allocDir.AllocDir)
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}, func(err error) {
|
||||
require.Fail(t, "err: %v", err)
|
||||
})
|
||||
|
||||
// Send the destroy signal and ensure the AllocRunner cleans up.
|
||||
ar.Destroy()
|
||||
|
||||
testutil.WaitForResult(func() (bool, error) {
|
||||
last := upd.Last()
|
||||
if last == nil {
|
||||
return false, fmt.Errorf("No updates")
|
||||
}
|
||||
|
||||
// Check the status has changed.
|
||||
if last.ClientStatus != structs.AllocClientStatusComplete {
|
||||
return false, fmt.Errorf("got client status %v; want %v", last.ClientStatus, structs.AllocClientStatusComplete)
|
||||
}
|
||||
|
||||
// Check the alloc directory was cleaned
|
||||
if _, err := os.Stat(ar.allocDir.AllocDir); err == nil {
|
||||
return false, fmt.Errorf("alloc dir still exists: %v", ar.allocDir.AllocDir)
|
||||
} else if !os.IsNotExist(err) {
|
||||
return false, fmt.Errorf("stat err: %v", err)
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}, func(err error) {
|
||||
require.Fail(t, "err: %v", err)
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue