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  }