2020-08-18 17:49:50 +00:00
|
|
|
package lifecycle
|
|
|
|
|
|
|
|
import (
|
2020-08-20 15:07:18 +00:00
|
|
|
"fmt"
|
2020-08-31 20:22:41 +00:00
|
|
|
|
2020-08-18 17:49:50 +00:00
|
|
|
"github.com/hashicorp/nomad/api"
|
|
|
|
"github.com/hashicorp/nomad/e2e/e2eutil"
|
|
|
|
"github.com/hashicorp/nomad/e2e/framework"
|
|
|
|
"github.com/hashicorp/nomad/helper/uuid"
|
|
|
|
"github.com/hashicorp/nomad/nomad/structs"
|
2020-08-20 15:07:18 +00:00
|
|
|
"github.com/hashicorp/nomad/testutil"
|
2020-08-18 17:49:50 +00:00
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
)
|
|
|
|
|
|
|
|
type LifecycleE2ETest struct {
|
|
|
|
framework.TC
|
|
|
|
jobIDs []string
|
|
|
|
}
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
framework.AddSuites(&framework.TestSuite{
|
2020-08-31 20:22:41 +00:00
|
|
|
Component: "Lifecycle",
|
2020-08-18 17:49:50 +00:00
|
|
|
CanRunLocal: true,
|
|
|
|
Cases: []framework.TestCase{new(LifecycleE2ETest)},
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ensure cluster has leader and at least 1 client node
|
|
|
|
// in a ready state before running tests
|
|
|
|
func (tc *LifecycleE2ETest) BeforeAll(f *framework.F) {
|
|
|
|
e2eutil.WaitForLeader(f.T(), tc.Nomad())
|
|
|
|
e2eutil.WaitForNodesReady(f.T(), tc.Nomad(), 1)
|
|
|
|
}
|
|
|
|
|
|
|
|
// TestBatchJob runs a batch job with prestart and poststop hooks
|
|
|
|
func (tc *LifecycleE2ETest) TestBatchJob(f *framework.F) {
|
|
|
|
t := f.T()
|
|
|
|
require := require.New(t)
|
|
|
|
nomadClient := tc.Nomad()
|
|
|
|
uuid := uuid.Generate()
|
|
|
|
jobID := "lifecycle-" + uuid[0:8]
|
|
|
|
tc.jobIDs = append(tc.jobIDs, jobID)
|
|
|
|
|
|
|
|
allocs := e2eutil.RegisterAndWaitForAllocs(f.T(), nomadClient, "lifecycle/inputs/batch.nomad", jobID, "")
|
|
|
|
require.Equal(1, len(allocs))
|
|
|
|
allocID := allocs[0].ID
|
|
|
|
|
|
|
|
// wait for the job to stop and assert we stopped successfully, not failed
|
|
|
|
e2eutil.WaitForAllocStopped(t, nomadClient, allocID)
|
|
|
|
alloc, _, err := nomadClient.Allocations().Info(allocID, nil)
|
|
|
|
require.NoError(err)
|
|
|
|
require.Equal(structs.AllocClientStatusComplete, alloc.ClientStatus)
|
|
|
|
|
|
|
|
// assert the files were written as expected
|
|
|
|
afi, _, err := nomadClient.AllocFS().List(alloc, "alloc", nil)
|
|
|
|
require.NoError(err)
|
|
|
|
expected := map[string]bool{
|
2020-11-12 16:01:42 +00:00
|
|
|
"init-ran": true, "main-ran": true, "poststart-ran": true, "poststop-ran": true,
|
2020-08-18 17:49:50 +00:00
|
|
|
"init-running": false, "main-running": false, "poststart-running": false}
|
|
|
|
got := checkFiles(expected, afi)
|
|
|
|
require.Equal(expected, got)
|
|
|
|
}
|
|
|
|
|
|
|
|
// TestServiceJob runs a service job with prestart and poststop hooks
|
|
|
|
func (tc *LifecycleE2ETest) TestServiceJob(f *framework.F) {
|
|
|
|
t := f.T()
|
|
|
|
require := require.New(t)
|
|
|
|
nomadClient := tc.Nomad()
|
|
|
|
uuid := uuid.Generate()
|
|
|
|
jobID := "lifecycle-" + uuid[0:8]
|
|
|
|
tc.jobIDs = append(tc.jobIDs, jobID)
|
|
|
|
|
|
|
|
allocs := e2eutil.RegisterAndWaitForAllocs(f.T(), nomadClient, "lifecycle/inputs/service.nomad", jobID, "")
|
|
|
|
require.Equal(1, len(allocs))
|
|
|
|
allocID := allocs[0].ID
|
|
|
|
|
2020-08-20 15:07:18 +00:00
|
|
|
//e2eutil.WaitForAllocRunning(t, nomadClient, allocID)
|
|
|
|
testutil.WaitForResult(func() (bool, error) {
|
|
|
|
alloc, _, err := nomadClient.Allocations().Info(allocID, nil)
|
|
|
|
if err != nil {
|
|
|
|
return false, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if alloc.ClientStatus != structs.AllocClientStatusRunning {
|
|
|
|
return false, fmt.Errorf("expected status running, but was: %s", alloc.ClientStatus)
|
|
|
|
}
|
|
|
|
|
2020-08-20 15:49:58 +00:00
|
|
|
if alloc.TaskStates["poststart"].FinishedAt.IsZero() {
|
2020-08-20 15:07:18 +00:00
|
|
|
return false, fmt.Errorf("poststart task hasn't started")
|
|
|
|
}
|
|
|
|
|
2020-08-20 15:49:58 +00:00
|
|
|
afi, _, err := nomadClient.AllocFS().List(alloc, "alloc", nil)
|
|
|
|
if err != nil {
|
|
|
|
return false, err
|
|
|
|
}
|
|
|
|
expected := map[string]bool{
|
|
|
|
"main-checked": true}
|
|
|
|
got := checkFiles(expected, afi)
|
|
|
|
if !got["main-checked"] {
|
|
|
|
return false, fmt.Errorf("main-checked file has not been written")
|
|
|
|
}
|
|
|
|
|
2020-08-20 15:07:18 +00:00
|
|
|
return true, nil
|
|
|
|
}, func(err error) {
|
|
|
|
t.Fatalf("failed to wait on alloc: %v", err)
|
|
|
|
})
|
2020-08-18 17:49:50 +00:00
|
|
|
|
|
|
|
alloc, _, err := nomadClient.Allocations().Info(allocID, nil)
|
|
|
|
require.NoError(err)
|
|
|
|
|
2020-08-20 15:49:58 +00:00
|
|
|
require.False(alloc.TaskStates["poststart"].Failed)
|
|
|
|
|
2020-08-18 17:49:50 +00:00
|
|
|
// stop the job
|
|
|
|
_, _, err = nomadClient.Jobs().Deregister(jobID, false, nil)
|
|
|
|
require.NoError(err)
|
|
|
|
e2eutil.WaitForAllocStopped(t, nomadClient, allocID)
|
|
|
|
|
2020-11-12 16:01:42 +00:00
|
|
|
require.False(alloc.TaskStates["poststop"].Failed)
|
|
|
|
|
2020-08-18 17:49:50 +00:00
|
|
|
// assert the files were written as expected
|
|
|
|
afi, _, err := nomadClient.AllocFS().List(alloc, "alloc", nil)
|
|
|
|
require.NoError(err)
|
|
|
|
expected := map[string]bool{
|
2020-11-12 16:01:42 +00:00
|
|
|
"init-ran": true, "sidecar-ran": true, "main-ran": true, "poststart-ran": true, "poststop-ran": true,
|
|
|
|
"poststart-started": true, "main-started": true, "poststop-started": true,
|
|
|
|
"init-running": false, "poststart-running": false, "poststop-running": false,
|
2020-08-20 15:49:58 +00:00
|
|
|
"main-checked": true}
|
2020-08-18 17:49:50 +00:00
|
|
|
got := checkFiles(expected, afi)
|
|
|
|
require.Equal(expected, got)
|
|
|
|
}
|
|
|
|
|
|
|
|
// checkFiles returns a map of whether the expected files were found
|
|
|
|
// in the file info response
|
|
|
|
func checkFiles(expected map[string]bool, got []*api.AllocFileInfo) map[string]bool {
|
|
|
|
results := map[string]bool{}
|
|
|
|
for expect := range expected {
|
|
|
|
results[expect] = false
|
|
|
|
}
|
|
|
|
for _, file := range got {
|
|
|
|
// there will be files unrelated to the test, so ignore those
|
|
|
|
if _, ok := results[file.Name]; ok {
|
|
|
|
results[file.Name] = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return results
|
|
|
|
}
|