github.com/bigcommerce/nomad@v0.9.3-bc/e2e/e2eutil/utils.go (about) 1 package e2eutil 2 3 import ( 4 "fmt" 5 "testing" 6 "time" 7 8 "github.com/hashicorp/nomad/api" 9 "github.com/hashicorp/nomad/helper" 10 "github.com/hashicorp/nomad/jobspec" 11 "github.com/hashicorp/nomad/nomad/structs" 12 "github.com/hashicorp/nomad/testutil" 13 "github.com/kr/pretty" 14 . "github.com/onsi/gomega" 15 "github.com/stretchr/testify/require" 16 ) 17 18 // retries is used to control how many times to retry checking if the cluster has a leader yet 19 const retries = 500 20 21 func WaitForLeader(t *testing.T, nomadClient *api.Client) { 22 statusAPI := nomadClient.Status() 23 24 testutil.WaitForResultRetries(retries, func() (bool, error) { 25 leader, err := statusAPI.Leader() 26 return leader != "", err 27 }, func(err error) { 28 t.Fatalf("failed to find leader: %v", err) 29 }) 30 } 31 32 // WaitForNodesReady waits until at least `nodes` number of nodes are ready or 33 // fails the test. 34 func WaitForNodesReady(t *testing.T, nomadClient *api.Client, nodes int) { 35 nodesAPI := nomadClient.Nodes() 36 37 testutil.WaitForResultRetries(retries, func() (bool, error) { 38 defer time.Sleep(time.Millisecond * 100) 39 nodesList, _, err := nodesAPI.List(nil) 40 if err != nil { 41 return false, fmt.Errorf("error listing nodes: %v", err) 42 } 43 44 eligibleNodes := 0 45 for _, node := range nodesList { 46 if node.Status == "ready" { 47 eligibleNodes++ 48 } 49 } 50 51 return eligibleNodes >= nodes, fmt.Errorf("only %d nodes ready (wanted at least %d)", eligibleNodes, nodes) 52 }, func(err error) { 53 t.Fatalf("failed to get enough ready nodes: %v", err) 54 }) 55 } 56 57 func RegisterAllocs(t *testing.T, nomadClient *api.Client, jobFile string, jobID string) []*api.AllocationListStub { 58 // Parse job 59 job, err := jobspec.ParseFile(jobFile) 60 require := require.New(t) 61 require.Nil(err) 62 job.ID = helper.StringToPtr(jobID) 63 64 // Register job 65 jobs := nomadClient.Jobs() 66 testutil.WaitForResult(func() (bool, error) { 67 resp, _, err := jobs.Register(job, nil) 68 if err != nil { 69 return false, err 70 } 71 return resp.EvalID != "", fmt.Errorf("expected EvalID:%s", pretty.Sprint(resp)) 72 }, func(err error) { 73 require.NoError(err) 74 }) 75 76 allocs, _, _ := jobs.Allocations(jobID, false, nil) 77 return allocs 78 } 79 80 func RegisterAndWaitForAllocs(t *testing.T, nomadClient *api.Client, jobFile string, jobID string) []*api.AllocationListStub { 81 require := require.New(t) 82 g := NewGomegaWithT(t) 83 jobs := nomadClient.Jobs() 84 85 // Start allocations 86 RegisterAllocs(t, nomadClient, jobFile, jobID) 87 88 // Wrap in retry to wait until placement 89 g.Eventually(func() []*api.AllocationListStub { 90 // Look for allocations 91 allocs, _, _ := jobs.Allocations(jobID, false, nil) 92 return allocs 93 }, 30*time.Second, time.Second).ShouldNot(BeEmpty()) 94 95 allocs, _, err := jobs.Allocations(jobID, false, nil) 96 require.NoError(err) 97 return allocs 98 } 99 100 func WaitForAllocRunning(t *testing.T, nomadClient *api.Client, allocID string) { 101 testutil.WaitForResultRetries(retries, func() (bool, error) { 102 time.Sleep(time.Millisecond * 100) 103 alloc, _, err := nomadClient.Allocations().Info(allocID, nil) 104 if err != nil { 105 return false, err 106 } 107 108 return alloc.ClientStatus == structs.AllocClientStatusRunning, fmt.Errorf("expected status running, but was: %s", alloc.ClientStatus) 109 }, func(err error) { 110 t.Fatalf("failed to wait on alloc: %v", err) 111 }) 112 } 113 114 func DeploymentsForJob(t *testing.T, nomadClient *api.Client, jobID string) []*api.Deployment { 115 ds, _, err := nomadClient.Deployments().List(nil) 116 require.NoError(t, err) 117 118 out := []*api.Deployment{} 119 for _, d := range ds { 120 if d.JobID == jobID { 121 out = append(out, d) 122 } 123 } 124 125 return out 126 } 127 128 func WaitForDeployment(t *testing.T, nomadClient *api.Client, deployID string, status string, statusDesc string) { 129 testutil.WaitForResultRetries(retries, func() (bool, error) { 130 time.Sleep(time.Millisecond * 100) 131 deploy, _, err := nomadClient.Deployments().Info(deployID, nil) 132 if err != nil { 133 return false, err 134 } 135 136 if deploy.Status == status && deploy.StatusDescription == statusDesc { 137 return true, nil 138 } 139 return false, fmt.Errorf("expected status %s \"%s\", but got: %s \"%s\"", 140 status, 141 statusDesc, 142 deploy.Status, 143 deploy.StatusDescription, 144 ) 145 146 }, func(err error) { 147 t.Fatalf("failed to wait on deployment: %v", err) 148 }) 149 }