open-nomad/command/job_stop_test.go
Seth Hoenig 92dfa41286
command: fixup tests concerning multi job stop (#15606)
* command: fixup job multi-stop test

This PR refactors the StopCommand test that runs 10 jobs and then
passes them all to one invokation of 'job stop'.

* test: swap use of assert for must

* test: cleanup job files we create

* command: fixup job stop failure tests

Now that JobStop works on concurrent jobs, the error messages are
different.

* cleanup: use multiple post scripts
2022-12-21 16:21:48 -06:00

151 lines
3.7 KiB
Go

package command
import (
"encoding/json"
"os"
"path/filepath"
"testing"
"github.com/hashicorp/nomad/ci"
"github.com/hashicorp/nomad/command/agent"
"github.com/hashicorp/nomad/helper/pointer"
"github.com/hashicorp/nomad/helper/uuid"
"github.com/hashicorp/nomad/nomad/mock"
"github.com/hashicorp/nomad/nomad/structs"
"github.com/mitchellh/cli"
"github.com/posener/complete"
"github.com/shoenig/test/must"
)
var _ cli.Command = (*JobStopCommand)(nil)
func TestStopCommand_multi(t *testing.T) {
ci.Parallel(t)
srv, _, addr := testServer(t, true, func(c *agent.Config) {
c.DevMode = true
})
defer srv.Shutdown()
// the number of jobs we want to run
numJobs := 10
// create and run a handful of jobs
jobIDs := make([]string, 0, numJobs)
for i := 0; i < numJobs; i++ {
jobID := uuid.Generate()
jobIDs = append(jobIDs, jobID)
}
jobFilePath := func(jobID string) string {
return filepath.Join(os.TempDir(), jobID+".nomad")
}
// cleanup job files we will create
t.Cleanup(func() {
for _, jobID := range jobIDs {
_ = os.Remove(jobFilePath(jobID))
}
})
// record cli output
ui := cli.NewMockUi()
for _, jobID := range jobIDs {
job := testJob(jobID)
job.TaskGroups[0].Tasks[0].Resources.MemoryMB = pointer.Of(16)
job.TaskGroups[0].Tasks[0].Resources.DiskMB = pointer.Of(32)
job.TaskGroups[0].Tasks[0].Resources.CPU = pointer.Of(10)
job.TaskGroups[0].Tasks[0].Config = map[string]interface{}{
"run_for": "30s",
}
jobJSON, err := json.MarshalIndent(job, "", " ")
must.NoError(t, err)
jobFile := jobFilePath(jobID)
err = os.WriteFile(jobFile, []byte(jobJSON), 0o644)
must.NoError(t, err)
cmd := &JobRunCommand{Meta: Meta{Ui: ui}}
code := cmd.Run([]string{"-address", addr, "-json", jobFile})
must.Zero(t, code,
must.Sprintf("job stop stdout: %s", ui.OutputWriter.String()),
must.Sprintf("job stop stderr: %s", ui.ErrorWriter.String()),
)
}
// helper for stopping a list of jobs
stop := func(args ...string) (stdout string, stderr string, code int) {
cmd := &JobStopCommand{Meta: Meta{Ui: ui}}
code = cmd.Run(args)
return ui.OutputWriter.String(), ui.ErrorWriter.String(), code
}
// stop all jobs in one command
args := []string{"-address", addr, "-detach"}
args = append(args, jobIDs...)
stdout, stderr, code := stop(args...)
must.Zero(t, code,
must.Sprintf("job stop stdout: %s", stdout),
must.Sprintf("job stop stderr: %s", stderr),
)
}
func TestStopCommand_Fails(t *testing.T) {
ci.Parallel(t)
srv, _, url := testServer(t, false, nil)
defer srv.Shutdown()
ui := cli.NewMockUi()
cmd := &JobStopCommand{Meta: Meta{Ui: ui}}
// Fails on misuse
code := cmd.Run([]string{"-some", "-bad", "-args"})
must.One(t, code)
out := ui.ErrorWriter.String()
must.StrContains(t, out, "flag provided but not defined: -some")
ui.ErrorWriter.Reset()
// Fails on nonexistent job ID
code = cmd.Run([]string{"-address=" + url, "nope"})
must.One(t, code)
out = ui.ErrorWriter.String()
must.StrContains(t, out, "No job(s) with prefix or id")
ui.ErrorWriter.Reset()
// Fails on connection failure
code = cmd.Run([]string{"-address=nope", "nope"})
must.One(t, code)
out = ui.ErrorWriter.String()
must.StrContains(t, out, "Error finding jobs with prefix: nope")
}
func TestStopCommand_AutocompleteArgs(t *testing.T) {
ci.Parallel(t)
srv, _, url := testServer(t, true, nil)
defer srv.Shutdown()
ui := cli.NewMockUi()
cmd := &JobStopCommand{Meta: Meta{Ui: ui, flagAddress: url}}
// Create a fake job
state := srv.Agent.Server().State()
j := mock.Job()
must.NoError(t, state.UpsertJob(structs.MsgTypeTestSetup, 1000, j))
prefix := j.ID[:len(j.ID)-5]
args := complete.Args{Last: prefix}
predictor := cmd.AutocompleteArgs()
res := predictor.Predict(args)
must.Len(t, 1, res)
must.Eq(t, j.ID, res[0])
}