Repository: hashicorp/nomad
File: scheduler/generic_sched_test.go (Go)

Code before:
	node := mock.Node()
	require.NoError(t, h.State.UpsertNode(structs.MsgTypeTestSetup, h.NextIndex(), node))

	// Create a job
	job := mock.Job()
	job.TaskGroups[0].Tasks[0].Resources.Cores = 1
	job.TaskGroups[0].Count = 3
	require.NoError(t, h.State.UpsertJob(structs.MsgTypeTestSetup, h.NextIndex(), nil, job))

	// Create a mock evaluation to register the job
	eval := &structs.Evaluation{
		Namespace:   structs.DefaultNamespace,
		ID:          uuid.Generate(),
		Priority:    job.Priority,
		TriggeredBy: structs.EvalTriggerJobRegister,
		JobID:       job.ID,
		Status:      structs.EvalStatusPending,
	}

	require.NoError(t, h.State.UpsertEvals(structs.MsgTypeTestSetup, h.NextIndex(), []*structs.Evaluation{eval}))

	// Process the evaluation
	err := h.Process(NewServiceScheduler, eval)
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	// Ensure a single plan
	if len(h.Plans) != 1 {
		t.Fatalf("bad: %#v", h.Plans)
	}
	plan := h.Plans[0]

	// Ensure the eval has no spawned blocked eval
	assert.Len(t, h.CreateEvals, 0, "Created Evals")
	require.Equal(t, "", h.Evals[0].BlockedEval, "did not expect a blocked eval")

	// Ensure the plan allocated
	var planned []*structs.Allocation
	for _, allocList := range plan.NodeAllocation {
		planned = append(planned, allocList...)
	}

	if len(planned) != 3 {
		t.Fatalf("bad: %#v", plan)
	}

	// Lookup the allocations by JobID
	ws := memdb.NewWatchSet()
	out, err := h.State.AllocsByJob(ws, job.Namespace, job.ID, false)
	require.NoError(t, err)

Review comment (bug):
I realize we're probably just copying what nearby tests are doing, but on Nomad we're trying to gradually get everything migrated over to use https://pkg.go.dev/github.com/shoenig/test (from one of our former colleagues Seth). 

This is a `testify`-like library but uses generics to fix some subtle but fairly serious correctness bugs in `testify` that upstream isn't willing to break backcompat for. And it improves a couple of ergonomics issues in terms of being consistent with the argument order (expected vs actual). It also has some nice pretty-printing on failure so we don't need to add extra logging in the test.

So here we can do:

```suggestion
	must.NoError(t, err)
```

Anywhere we're using `require` in this test we can use `must` instead (ex. `must.Len` below), and anywhere we're using the non-fatal `assert` we can use `test` instead. 

Code after:
}

func initNodeAndAllocs(t *testing.T, h *Harness, job *structs.Job,
	nodeStatus, clientStatus string) (*structs.Node, *structs.Job, []*structs.Allocation) {
	// Node, which is ready
	node := mock.Node()
	node.Status = nodeStatus
	require.NoError(t, h.State.UpsertNode(structs.MsgTypeTestSetup, h.NextIndex(), node))

	allocs := make([]*structs.Allocation, job.TaskGroups[0].Count)
	for i := 0; i < job.TaskGroups[0].Count; i++ {
		// Alloc for the running group
		alloc := mock.Alloc()
		alloc.Job = job
		alloc.JobID = job.ID
		alloc.NodeID = node.ID
		alloc.Name = fmt.Sprintf("my-job.web[%d]", i)
		alloc.DesiredStatus = structs.AllocDesiredStatusRun
		alloc.ClientStatus = clientStatus

		allocs[i] = alloc
	}

	require.NoError(t, h.State.UpsertAllocs(structs.MsgTypeTestSetup, h.NextIndex(), allocs))
	return node, job, allocs

}