2017-04-04 22:02:09 +00:00
|
|
|
// +build !windows
|
|
|
|
|
|
|
|
package client
|
|
|
|
|
|
|
|
import (
|
|
|
|
"syscall"
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/hashicorp/nomad/client/vaultclient"
|
|
|
|
"github.com/hashicorp/nomad/nomad/mock"
|
|
|
|
"github.com/hashicorp/nomad/nomad/structs"
|
|
|
|
)
|
|
|
|
|
|
|
|
// This test is just to make sure we are resilient to failures when a restart or
|
|
|
|
// signal is triggered and the task is not running.
|
|
|
|
func TestTaskRunner_RestartSignalTask_NotRunning(t *testing.T) {
|
|
|
|
alloc := mock.Alloc()
|
|
|
|
task := alloc.Job.TaskGroups[0].Tasks[0]
|
|
|
|
task.Driver = "mock_driver"
|
|
|
|
task.Config = map[string]interface{}{
|
|
|
|
"exit_code": "0",
|
|
|
|
"run_for": "100s",
|
|
|
|
}
|
|
|
|
|
|
|
|
// Use vault to block the start
|
|
|
|
task.Vault = &structs.Vault{Policies: []string{"default"}}
|
|
|
|
|
|
|
|
ctx := testTaskRunnerFromAlloc(t, true, alloc)
|
|
|
|
ctx.tr.MarkReceived()
|
|
|
|
defer ctx.Cleanup()
|
|
|
|
|
|
|
|
// Control when we get a Vault token
|
|
|
|
token := "1234"
|
|
|
|
waitCh := make(chan struct{})
|
|
|
|
defer close(waitCh)
|
|
|
|
handler := func(*structs.Allocation, []string) (map[string]string, error) {
|
|
|
|
<-waitCh
|
|
|
|
return map[string]string{task.Name: token}, nil
|
|
|
|
}
|
|
|
|
ctx.tr.vaultClient.(*vaultclient.MockVaultClient).DeriveTokenFn = handler
|
|
|
|
go ctx.tr.Run()
|
|
|
|
|
|
|
|
select {
|
|
|
|
case <-ctx.tr.WaitCh():
|
|
|
|
t.Fatalf("premature exit")
|
|
|
|
case <-time.After(1 * time.Second):
|
|
|
|
}
|
|
|
|
|
|
|
|
// Send a signal and restart
|
|
|
|
if err := ctx.tr.Signal("test", "don't panic", syscall.SIGCHLD); err != nil {
|
|
|
|
t.Fatalf("Signalling errored: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Send a restart
|
2017-09-13 06:15:46 +00:00
|
|
|
ctx.tr.Restart("test", "don't panic", false)
|
2017-04-04 22:02:09 +00:00
|
|
|
|
|
|
|
if len(ctx.upd.events) != 2 {
|
|
|
|
t.Fatalf("should have 2 ctx.updates: %#v", ctx.upd.events)
|
|
|
|
}
|
|
|
|
|
|
|
|
if ctx.upd.state != structs.TaskStatePending {
|
|
|
|
t.Fatalf("TaskState %v; want %v", ctx.upd.state, structs.TaskStatePending)
|
|
|
|
}
|
|
|
|
|
|
|
|
if ctx.upd.events[0].Type != structs.TaskReceived {
|
|
|
|
t.Fatalf("First Event was %v; want %v", ctx.upd.events[0].Type, structs.TaskReceived)
|
|
|
|
}
|
|
|
|
|
|
|
|
if ctx.upd.events[1].Type != structs.TaskSetup {
|
|
|
|
t.Fatalf("Second Event was %v; want %v", ctx.upd.events[1].Type, structs.TaskSetup)
|
|
|
|
}
|
|
|
|
}
|