2019-12-04 20:44:21 +00:00
|
|
|
package allocrunner
|
|
|
|
|
|
|
|
import (
|
|
|
|
"testing"
|
2019-12-19 17:45:39 +00:00
|
|
|
"time"
|
|
|
|
|
2020-01-27 18:47:56 +00:00
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
|
2019-12-19 17:45:39 +00:00
|
|
|
"github.com/hashicorp/nomad/nomad/structs"
|
2019-12-04 20:44:21 +00:00
|
|
|
|
|
|
|
"github.com/hashicorp/nomad/helper/testlog"
|
|
|
|
"github.com/hashicorp/nomad/nomad/mock"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestTaskHookCoordinator_OnlyMainApp(t *testing.T) {
|
|
|
|
alloc := mock.Alloc()
|
|
|
|
tasks := alloc.Job.TaskGroups[0].Tasks
|
2020-01-27 18:47:56 +00:00
|
|
|
task := tasks[0]
|
2019-12-04 20:44:21 +00:00
|
|
|
logger := testlog.HCLogger(t)
|
|
|
|
|
|
|
|
coord := newTaskHookCoordinator(logger, tasks)
|
|
|
|
|
2020-01-27 18:47:56 +00:00
|
|
|
ch := coord.startConditionForTask(task)
|
2019-12-04 20:44:21 +00:00
|
|
|
|
2020-01-27 18:47:56 +00:00
|
|
|
require.Truef(t, isChannelClosed(ch), "%s channel was open, should be closed", task.Name)
|
2019-12-04 20:44:21 +00:00
|
|
|
}
|
2019-12-16 19:08:36 +00:00
|
|
|
|
2019-12-19 17:45:39 +00:00
|
|
|
func TestTaskHookCoordinator_PrestartRunsBeforeMain(t *testing.T) {
|
|
|
|
logger := testlog.HCLogger(t)
|
|
|
|
|
2019-12-16 19:08:36 +00:00
|
|
|
alloc := mock.Alloc()
|
|
|
|
tasks := alloc.Job.TaskGroups[0].Tasks
|
2019-12-19 17:45:39 +00:00
|
|
|
tasks = append(tasks, initTask())
|
|
|
|
tasks = append(tasks, sidecarTask())
|
2019-12-16 19:08:36 +00:00
|
|
|
|
2020-01-27 18:47:56 +00:00
|
|
|
mainTask := tasks[0]
|
|
|
|
initTask := tasks[1]
|
|
|
|
sideTask := tasks[2]
|
2019-12-19 17:45:39 +00:00
|
|
|
|
2020-01-27 18:47:56 +00:00
|
|
|
coord := newTaskHookCoordinator(logger, tasks)
|
|
|
|
mainCh := coord.startConditionForTask(mainTask)
|
|
|
|
initCh := coord.startConditionForTask(initTask)
|
|
|
|
sideCh := coord.startConditionForTask(sideTask)
|
2019-12-19 17:45:39 +00:00
|
|
|
|
2020-01-27 18:47:56 +00:00
|
|
|
require.Falsef(t, isChannelClosed(mainCh), "%s channel was closed, should be open", mainTask.Name)
|
|
|
|
require.Truef(t, isChannelClosed(initCh), "%s channel was open, should be closed", initTask.Name)
|
|
|
|
require.Truef(t, isChannelClosed(sideCh), "%s channel was open, should be closed", sideTask.Name)
|
2019-12-19 17:45:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestTaskHookCoordinator_MainRunsAfterPrestart(t *testing.T) {
|
|
|
|
logger := testlog.HCLogger(t)
|
|
|
|
|
|
|
|
alloc := mock.Alloc()
|
|
|
|
tasks := alloc.Job.TaskGroups[0].Tasks
|
|
|
|
tasks = append(tasks, initTask())
|
|
|
|
tasks = append(tasks, sidecarTask())
|
2019-12-16 19:08:36 +00:00
|
|
|
|
2019-12-19 17:45:39 +00:00
|
|
|
coord := newTaskHookCoordinator(logger, tasks)
|
2019-12-16 19:08:36 +00:00
|
|
|
mainCh := coord.startConditionForTask(tasks[0])
|
|
|
|
initCh := coord.startConditionForTask(tasks[1])
|
|
|
|
sideCh := coord.startConditionForTask(tasks[2])
|
|
|
|
|
2019-12-19 17:45:39 +00:00
|
|
|
mainTaskName := tasks[0].Name
|
|
|
|
initTaskName := tasks[1].Name
|
|
|
|
sideTaskName := tasks[2].Name
|
|
|
|
|
2020-01-27 18:47:56 +00:00
|
|
|
require.Falsef(t, isChannelClosed(mainCh), "%s channel was closed, should be open", mainTaskName)
|
|
|
|
require.Truef(t, isChannelClosed(initCh), "%s channel was open, should be closed", initTaskName)
|
|
|
|
require.Truef(t, isChannelClosed(sideCh), "%s channel was open, should be closed", sideTaskName)
|
2019-12-19 17:45:39 +00:00
|
|
|
|
|
|
|
states := map[string]*structs.TaskState{
|
|
|
|
mainTaskName: &structs.TaskState{
|
|
|
|
State: structs.TaskStatePending,
|
|
|
|
Failed: false,
|
|
|
|
},
|
|
|
|
initTaskName: &structs.TaskState{
|
|
|
|
State: structs.TaskStateDead,
|
|
|
|
Failed: false,
|
|
|
|
StartedAt: time.Now(),
|
|
|
|
FinishedAt: time.Now(),
|
|
|
|
},
|
|
|
|
sideTaskName: &structs.TaskState{
|
|
|
|
State: structs.TaskStateRunning,
|
|
|
|
Failed: false,
|
|
|
|
StartedAt: time.Now(),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
coord.taskStateUpdated(states)
|
|
|
|
|
2020-01-27 18:47:56 +00:00
|
|
|
require.Truef(t, isChannelClosed(initCh), "%s channel was open, should be closed", mainTaskName)
|
|
|
|
require.Truef(t, isChannelClosed(initCh), "%s channel was open, should be closed", initTaskName)
|
|
|
|
require.Truef(t, isChannelClosed(sideCh), "%s channel was open, should be closed", sideTaskName)
|
2019-12-19 17:45:39 +00:00
|
|
|
}
|
|
|
|
|
2020-01-27 18:47:56 +00:00
|
|
|
func isChannelClosed(ch <-chan struct{}) bool {
|
2019-12-16 19:08:36 +00:00
|
|
|
select {
|
2019-12-19 17:45:39 +00:00
|
|
|
case <-ch:
|
2020-01-27 18:47:56 +00:00
|
|
|
return true
|
2019-12-16 19:08:36 +00:00
|
|
|
default:
|
2020-01-27 18:47:56 +00:00
|
|
|
return false
|
2019-12-19 17:45:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func sidecarTask() *structs.Task {
|
|
|
|
return &structs.Task{
|
|
|
|
Name: "sidecar",
|
|
|
|
Lifecycle: &structs.TaskLifecycleConfig{
|
|
|
|
Hook: structs.TaskLifecycleHookPrestart,
|
|
|
|
BlockUntil: structs.TaskLifecycleBlockUntilRunning,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func initTask() *structs.Task {
|
|
|
|
return &structs.Task{
|
|
|
|
Name: "init",
|
|
|
|
Lifecycle: &structs.TaskLifecycleConfig{
|
|
|
|
Hook: structs.TaskLifecycleHookPrestart,
|
|
|
|
BlockUntil: structs.TaskLifecycleBlockUntilCompleted,
|
|
|
|
},
|
2019-12-16 19:08:36 +00:00
|
|
|
}
|
|
|
|
}
|