github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/command/testing_test.go (about) 1 package command 2 3 import ( 4 "fmt" 5 "os" 6 "testing" 7 "time" 8 9 "github.com/hashicorp/nomad/api" 10 "github.com/hashicorp/nomad/command/agent" 11 "github.com/hashicorp/nomad/helper/pointer" 12 "github.com/hashicorp/nomad/nomad/structs" 13 "github.com/hashicorp/nomad/testutil" 14 "github.com/shoenig/test/must" 15 ) 16 17 func testServer(t *testing.T, runClient bool, cb func(*agent.Config)) (*agent.TestAgent, *api.Client, string) { 18 // Make a new test server 19 a := agent.NewTestAgent(t, t.Name(), func(config *agent.Config) { 20 config.Client.Enabled = runClient 21 22 if cb != nil { 23 cb(config) 24 } 25 }) 26 t.Cleanup(func() { _ = a.Shutdown() }) 27 28 c := a.Client() 29 return a, c, a.HTTPAddr() 30 } 31 32 // testClient starts a new test client, blocks until it joins, and performs 33 // cleanup after the test is complete. 34 func testClient(t *testing.T, name string, cb func(*agent.Config)) (*agent.TestAgent, *api.Client, string) { 35 t.Logf("Starting client agent %s", name) 36 a := agent.NewTestAgent(t, name, func(config *agent.Config) { 37 if cb != nil { 38 cb(config) 39 } 40 }) 41 t.Cleanup(func() { _ = a.Shutdown() }) 42 43 c := a.Client() 44 t.Logf("Waiting for client %s to join server(s) %s", name, a.GetConfig().Client.Servers) 45 testutil.WaitForClient(t, a.Agent.RPC, a.Agent.Client().NodeID(), a.Agent.Client().Region()) 46 47 return a, c, a.HTTPAddr() 48 } 49 50 func testJob(jobID string) *api.Job { 51 task := api.NewTask("task1", "mock_driver"). 52 SetConfig("kill_after", "1s"). 53 SetConfig("run_for", "5s"). 54 SetConfig("exit_code", 0). 55 Require(&api.Resources{ 56 MemoryMB: pointer.Of(256), 57 CPU: pointer.Of(100), 58 }). 59 SetLogConfig(&api.LogConfig{ 60 MaxFiles: pointer.Of(1), 61 MaxFileSizeMB: pointer.Of(2), 62 }) 63 64 group := api.NewTaskGroup("group1", 1). 65 AddTask(task). 66 RequireDisk(&api.EphemeralDisk{ 67 SizeMB: pointer.Of(20), 68 }) 69 70 job := api.NewBatchJob(jobID, jobID, "global", 1). 71 AddDatacenter("dc1"). 72 AddTaskGroup(group) 73 74 return job 75 } 76 77 func testNomadServiceJob(jobID string) *api.Job { 78 j := testJob(jobID) 79 j.TaskGroups[0].Services = []*api.Service{{ 80 Name: "service1", 81 PortLabel: "1000", 82 AddressMode: "", 83 Address: "127.0.0.1", 84 Checks: []api.ServiceCheck{{ 85 Name: "check1", 86 Type: "http", 87 Path: "/", 88 Interval: 1 * time.Second, 89 Timeout: 1 * time.Second, 90 }}, 91 Provider: "nomad", 92 }} 93 return j 94 } 95 96 func testMultiRegionJob(jobID, region, datacenter string) *api.Job { 97 task := api.NewTask("task1", "mock_driver"). 98 SetConfig("kill_after", "10s"). 99 SetConfig("run_for", "15s"). 100 SetConfig("exit_code", 0). 101 Require(&api.Resources{ 102 MemoryMB: pointer.Of(256), 103 CPU: pointer.Of(100), 104 }). 105 SetLogConfig(&api.LogConfig{ 106 MaxFiles: pointer.Of(1), 107 MaxFileSizeMB: pointer.Of(2), 108 }) 109 110 group := api.NewTaskGroup("group1", 1). 111 AddTask(task). 112 RequireDisk(&api.EphemeralDisk{ 113 SizeMB: pointer.Of(20), 114 }) 115 116 job := api.NewServiceJob(jobID, jobID, region, 1).AddDatacenter(datacenter).AddTaskGroup(group) 117 job.Region = nil 118 job.Multiregion = &api.Multiregion{ 119 Regions: []*api.MultiregionRegion{ 120 { 121 Name: "east", 122 Datacenters: []string{"east-1"}, 123 }, 124 { 125 Name: "west", 126 Datacenters: []string{"west-1"}, 127 }, 128 }, 129 } 130 131 return job 132 } 133 134 func waitForNodes(t *testing.T, client *api.Client) { 135 testutil.WaitForResult(func() (bool, error) { 136 nodes, _, err := client.Nodes().List(nil) 137 if err != nil { 138 return false, err 139 } 140 for _, node := range nodes { 141 if _, ok := node.Drivers["mock_driver"]; ok && 142 node.Status == structs.NodeStatusReady { 143 return true, nil 144 } 145 } 146 return false, fmt.Errorf("no ready nodes") 147 }, func(err error) { 148 must.NoError(t, err) 149 }) 150 } 151 152 func waitForAllocRunning(t *testing.T, client *api.Client, allocID string) { 153 testutil.WaitForResult(func() (bool, error) { 154 alloc, _, err := client.Allocations().Info(allocID, nil) 155 if err != nil { 156 return false, err 157 } 158 if alloc.ClientStatus == api.AllocClientStatusRunning { 159 return true, nil 160 } 161 return false, fmt.Errorf("alloc status: %s", alloc.ClientStatus) 162 }, func(err error) { 163 t.Fatalf("timed out waiting for alloc to be running: %v", err) 164 }) 165 } 166 167 func waitForCheckStatus(t *testing.T, client *api.Client, allocID, status string) { 168 testutil.WaitForResult(func() (bool, error) { 169 results, err := client.Allocations().Checks(allocID, nil) 170 if err != nil { 171 return false, err 172 } 173 174 // pick a check, any check will do 175 for _, check := range results { 176 if check.Status == status { 177 return true, nil 178 } 179 } 180 181 return false, fmt.Errorf("no check with status: %s", status) 182 }, func(err error) { 183 t.Fatalf("timed out waiting for alloc to be running: %v", err) 184 }) 185 } 186 187 func getAllocFromJob(t *testing.T, client *api.Client, jobID string) string { 188 var allocID string 189 if allocations, _, err := client.Jobs().Allocations(jobID, false, nil); err == nil { 190 if len(allocations) > 0 { 191 allocID = allocations[0].ID 192 } 193 } 194 must.NotEq(t, "", allocID, must.Sprint("expected to find an evaluation after running job", jobID)) 195 return allocID 196 } 197 198 func stopTestAgent(a *agent.TestAgent) { 199 _ = a.Shutdown() 200 } 201 202 func getTempFile(t *testing.T, name string) (string, func()) { 203 f, err := os.CreateTemp("", name) 204 must.NoError(t, err) 205 must.NoError(t, f.Close()) 206 return f.Name(), func() { 207 _ = os.Remove(f.Name()) 208 } 209 }