github.com/Ilhicas/nomad@v1.0.4-0.20210304152020-e86851182bc3/e2e/lifecycle/lifecycle.go (about) 1 package lifecycle 2 3 import ( 4 "fmt" 5 6 "github.com/hashicorp/nomad/api" 7 "github.com/hashicorp/nomad/e2e/e2eutil" 8 "github.com/hashicorp/nomad/e2e/framework" 9 "github.com/hashicorp/nomad/helper/uuid" 10 "github.com/hashicorp/nomad/nomad/structs" 11 "github.com/hashicorp/nomad/testutil" 12 "github.com/stretchr/testify/require" 13 ) 14 15 type LifecycleE2ETest struct { 16 framework.TC 17 jobIDs []string 18 } 19 20 func init() { 21 framework.AddSuites(&framework.TestSuite{ 22 Component: "Lifecycle", 23 CanRunLocal: true, 24 Cases: []framework.TestCase{new(LifecycleE2ETest)}, 25 }) 26 } 27 28 // Ensure cluster has leader and at least 1 client node 29 // in a ready state before running tests 30 func (tc *LifecycleE2ETest) BeforeAll(f *framework.F) { 31 e2eutil.WaitForLeader(f.T(), tc.Nomad()) 32 e2eutil.WaitForNodesReady(f.T(), tc.Nomad(), 1) 33 } 34 35 // TestBatchJob runs a batch job with prestart and poststop hooks 36 func (tc *LifecycleE2ETest) TestBatchJob(f *framework.F) { 37 t := f.T() 38 require := require.New(t) 39 nomadClient := tc.Nomad() 40 uuid := uuid.Generate() 41 jobID := "lifecycle-" + uuid[0:8] 42 tc.jobIDs = append(tc.jobIDs, jobID) 43 44 allocs := e2eutil.RegisterAndWaitForAllocs(f.T(), nomadClient, "lifecycle/inputs/batch.nomad", jobID, "") 45 require.Equal(1, len(allocs)) 46 allocID := allocs[0].ID 47 48 // wait for the job to stop and assert we stopped successfully, not failed 49 e2eutil.WaitForAllocStopped(t, nomadClient, allocID) 50 alloc, _, err := nomadClient.Allocations().Info(allocID, nil) 51 require.NoError(err) 52 require.Equal(structs.AllocClientStatusComplete, alloc.ClientStatus) 53 54 // assert the files were written as expected 55 afi, _, err := nomadClient.AllocFS().List(alloc, "alloc", nil) 56 require.NoError(err) 57 expected := map[string]bool{ 58 "init-ran": true, "main-ran": true, "poststart-ran": true, "poststop-ran": true, 59 "init-running": false, "main-running": false, "poststart-running": false} 60 got := checkFiles(expected, afi) 61 require.Equal(expected, got) 62 } 63 64 // TestServiceJob runs a service job with prestart and poststop hooks 65 func (tc *LifecycleE2ETest) TestServiceJob(f *framework.F) { 66 t := f.T() 67 require := require.New(t) 68 nomadClient := tc.Nomad() 69 uuid := uuid.Generate() 70 jobID := "lifecycle-" + uuid[0:8] 71 tc.jobIDs = append(tc.jobIDs, jobID) 72 73 allocs := e2eutil.RegisterAndWaitForAllocs(f.T(), nomadClient, "lifecycle/inputs/service.nomad", jobID, "") 74 require.Equal(1, len(allocs)) 75 allocID := allocs[0].ID 76 77 //e2eutil.WaitForAllocRunning(t, nomadClient, allocID) 78 testutil.WaitForResult(func() (bool, error) { 79 alloc, _, err := nomadClient.Allocations().Info(allocID, nil) 80 if err != nil { 81 return false, err 82 } 83 84 if alloc.ClientStatus != structs.AllocClientStatusRunning { 85 return false, fmt.Errorf("expected status running, but was: %s", alloc.ClientStatus) 86 } 87 88 if alloc.TaskStates["poststart"].FinishedAt.IsZero() { 89 return false, fmt.Errorf("poststart task hasn't started") 90 } 91 92 afi, _, err := nomadClient.AllocFS().List(alloc, "alloc", nil) 93 if err != nil { 94 return false, err 95 } 96 expected := map[string]bool{ 97 "main-checked": true} 98 got := checkFiles(expected, afi) 99 if !got["main-checked"] { 100 return false, fmt.Errorf("main-checked file has not been written") 101 } 102 103 return true, nil 104 }, func(err error) { 105 require.NoError(err, "failed to wait on alloc") 106 }) 107 108 alloc, _, err := nomadClient.Allocations().Info(allocID, nil) 109 require.NoError(err) 110 111 require.False(alloc.TaskStates["poststart"].Failed) 112 113 // stop the job 114 _, _, err = nomadClient.Jobs().Deregister(jobID, false, nil) 115 require.NoError(err) 116 e2eutil.WaitForAllocStopped(t, nomadClient, allocID) 117 118 require.False(alloc.TaskStates["poststop"].Failed) 119 120 // assert the files were written as expected 121 afi, _, err := nomadClient.AllocFS().List(alloc, "alloc", nil) 122 require.NoError(err) 123 expected := map[string]bool{ 124 "init-ran": true, "sidecar-ran": true, "main-ran": true, "poststart-ran": true, "poststop-ran": true, 125 "poststart-started": true, "main-started": true, "poststop-started": true, 126 "init-running": false, "poststart-running": false, "poststop-running": false, 127 "main-checked": true} 128 got := checkFiles(expected, afi) 129 require.Equal(expected, got) 130 } 131 132 // checkFiles returns a map of whether the expected files were found 133 // in the file info response 134 func checkFiles(expected map[string]bool, got []*api.AllocFileInfo) map[string]bool { 135 results := map[string]bool{} 136 for expect := range expected { 137 results[expect] = false 138 } 139 for _, file := range got { 140 // there will be files unrelated to the test, so ignore those 141 if _, ok := results[file.Name]; ok { 142 results[file.Name] = true 143 } 144 } 145 return results 146 }