From 9cc27b3c2cfeb1051a289aa359d094aec091a126 Mon Sep 17 00:00:00 2001 From: Seth Hoenig Date: Thu, 18 Aug 2022 08:51:53 -0500 Subject: [PATCH] cleanup: fixing warnings and refactoring of command package, part 2 This PR continues the cleanup of the command package, removing linter warnings, refactoring to use helpers, making tests easier to read, etc. --- command/agent_info_test.go | 55 ++++---- command/agent_monitor_test.go | 32 +++-- command/alloc_exec_test.go | 100 ++++++--------- command/alloc_fs_test.go | 97 +++++++------- command/alloc_logs_test.go | 73 ++++++----- command/alloc_restart_test.go | 145 +++++++++------------ command/alloc_signal_test.go | 112 ++++++++--------- command/alloc_status_test.go | 216 +++++++++++++++----------------- command/alloc_stop_test.go | 100 +++++++-------- command/check_test.go | 11 +- command/config_validate_test.go | 39 ++---- command/testing_test.go | 15 +++ 12 files changed, 441 insertions(+), 554 deletions(-) diff --git a/command/agent_info_test.go b/command/agent_info_test.go index 8b0869963..8902438a8 100644 --- a/command/agent_info_test.go +++ b/command/agent_info_test.go @@ -1,11 +1,11 @@ package command import ( - "strings" "testing" "github.com/hashicorp/nomad/ci" "github.com/mitchellh/cli" + "github.com/shoenig/test/must" ) func TestAgentInfoCommand_Implements(t *testing.T) { @@ -16,49 +16,43 @@ func TestAgentInfoCommand_Implements(t *testing.T) { func TestAgentInfoCommand_Run(t *testing.T) { ci.Parallel(t) srv, _, url := testServer(t, false, nil) - defer srv.Shutdown() + defer stopTestAgent(srv) ui := cli.NewMockUi() cmd := &AgentInfoCommand{Meta: Meta{Ui: ui}} code := cmd.Run([]string{"-address=" + url}) - if code != 0 { - t.Fatalf("expected exit 0, got: %d", code) - } + must.Zero(t, code) } func TestAgentInfoCommand_Run_JSON(t *testing.T) { ci.Parallel(t) srv, _, url := testServer(t, false, nil) - defer srv.Shutdown() + defer stopTestAgent(srv) ui := cli.NewMockUi() cmd := &AgentInfoCommand{Meta: Meta{Ui: ui}} code := cmd.Run([]string{"-address=" + url, "-json"}) - if code != 0 { - t.Fatalf("expected exit 0, got: %d", code) - } - if out := ui.OutputWriter.String(); !strings.Contains(out, "\"config\": {") { - t.Fatalf("expected config stanza in output json") - } + must.Zero(t, code) + + out := ui.OutputWriter.String() + must.StrContains(t, out, `"config"`) } func TestAgentInfoCommand_Run_Gotemplate(t *testing.T) { ci.Parallel(t) srv, _, url := testServer(t, false, nil) - defer srv.Shutdown() + defer stopTestAgent(srv) ui := cli.NewMockUi() cmd := &AgentInfoCommand{Meta: Meta{Ui: ui}} code := cmd.Run([]string{"-address=" + url, "-t", "{{.Stats.raft}}"}) - if code != 0 { - t.Fatalf("expected exit 0, got: %d", code) - } - if out := ui.OutputWriter.String(); !strings.Contains(out, "last_log_index") { - t.Fatalf("expected raft stats in gotemplate output") - } + must.Zero(t, code) + + out := ui.OutputWriter.String() + must.StrContains(t, out, "last_log_index") } func TestAgentInfoCommand_Fails(t *testing.T) { @@ -67,19 +61,18 @@ func TestAgentInfoCommand_Fails(t *testing.T) { cmd := &AgentInfoCommand{Meta: Meta{Ui: ui}} // Fails on misuse - if code := cmd.Run([]string{"some", "bad", "args"}); code != 1 { - t.Fatalf("expected exit code 1, got: %d", code) - } - if out := ui.ErrorWriter.String(); !strings.Contains(out, commandErrorText(cmd)) { - t.Fatalf("expected help output, got: %s", out) - } + code := cmd.Run([]string{"some", "bad", "args"}) + must.One(t, code) + + out := ui.ErrorWriter.String() + must.StrContains(t, out, commandErrorText(cmd)) + ui.ErrorWriter.Reset() // Fails on connection failure - if code := cmd.Run([]string{"-address=nope"}); code != 1 { - t.Fatalf("expected exit code 1, got: %d", code) - } - if out := ui.ErrorWriter.String(); !strings.Contains(out, "Error querying agent info") { - t.Fatalf("expected failed query error, got: %s", out) - } + code = cmd.Run([]string{"-address=nope"}) + must.One(t, code) + + out = ui.ErrorWriter.String() + must.StrContains(t, out, "Error querying agent info") } diff --git a/command/agent_monitor_test.go b/command/agent_monitor_test.go index cf8b186a0..bc9903dd6 100644 --- a/command/agent_monitor_test.go +++ b/command/agent_monitor_test.go @@ -1,11 +1,11 @@ package command import ( - "strings" "testing" "github.com/hashicorp/nomad/ci" "github.com/mitchellh/cli" + "github.com/shoenig/test/must" ) func TestMonitorCommand_Implements(t *testing.T) { @@ -16,31 +16,27 @@ func TestMonitorCommand_Implements(t *testing.T) { func TestMonitorCommand_Fails(t *testing.T) { ci.Parallel(t) srv, _, url := testServer(t, false, nil) - defer srv.Shutdown() + defer stopTestAgent(srv) ui := cli.NewMockUi() cmd := &MonitorCommand{Meta: Meta{Ui: ui}} // Fails on misuse - if code := cmd.Run([]string{"some", "bad", "args"}); code != 1 { - t.Fatalf("exepected exit code 1, got: %d", code) - } - if out := ui.ErrorWriter.String(); !strings.Contains(out, commandErrorText(cmd)) { - t.Fatalf("expected help output, got: %s", out) - } + code := cmd.Run([]string{"some", "bad", "args"}) + must.One(t, code) + + out := ui.ErrorWriter.String() + must.StrContains(t, out, commandErrorText(cmd)) ui.ErrorWriter.Reset() - if code := cmd.Run([]string{"-address=nope"}); code != 1 { - t.Fatalf("exepected exit code 1, got: %d", code) - } + code = cmd.Run([]string{"-address=nope"}) + must.One(t, code) // Fails on nonexistent node - if code := cmd.Run([]string{"-address=" + url, "-node-id=12345678-abcd-efab-cdef-123456789abc"}); code != 1 { - t.Fatalf("expected exit 1, got: %d", code) - } - if out := ui.ErrorWriter.String(); !strings.Contains(out, "No node(s) with prefix") { - t.Fatalf("expected not found error, got: %s", out) - } - ui.ErrorWriter.Reset() + code = cmd.Run([]string{"-address=" + url, "-node-id=12345678-abcd-efab-cdef-123456789abc"}) + must.One(t, code) + + out = ui.ErrorWriter.String() + must.StrContains(t, out, "No node(s) with prefix") } diff --git a/command/alloc_exec_test.go b/command/alloc_exec_test.go index e5586e4df..5de9d5ea3 100644 --- a/command/alloc_exec_test.go +++ b/command/alloc_exec_test.go @@ -13,8 +13,7 @@ import ( "github.com/hashicorp/nomad/testutil" "github.com/mitchellh/cli" "github.com/posener/complete" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/shoenig/test/must" ) // static check @@ -23,7 +22,7 @@ var _ cli.Command = &AllocExecCommand{} func TestAllocExecCommand_Fails(t *testing.T) { ci.Parallel(t) srv, client, url := testServer(t, true, nil) - defer srv.Shutdown() + defer stopTestAgent(srv) cases := []struct { name string @@ -83,32 +82,18 @@ func TestAllocExecCommand_Fails(t *testing.T) { cmd := &AllocExecCommand{Meta: Meta{Ui: ui}} code := cmd.Run(c.args) - require.Equal(t, 1, code) + must.One(t, code) - require.Contains(t, ui.ErrorWriter.String(), c.expectedError) + out := ui.ErrorWriter.String() + must.StrContains(t, out, c.expectedError) ui.ErrorWriter.Reset() ui.OutputWriter.Reset() - }) } // Wait for a node to be ready - testutil.WaitForResult(func() (bool, error) { - nodes, _, err := client.Nodes().List(nil) - if err != nil { - return false, err - } - for _, node := range nodes { - if _, ok := node.Drivers["mock_driver"]; ok && - node.Status == structs.NodeStatusReady { - return true, nil - } - } - return false, fmt.Errorf("no ready nodes") - }, func(err error) { - require.NoError(t, err) - }) + waitForNodes(t, client) t.Run("non existent task", func(t *testing.T) { ui := cli.NewMockUi() @@ -116,10 +101,12 @@ func TestAllocExecCommand_Fails(t *testing.T) { jobID := "job1_sfx" job1 := testJob(jobID) + resp, _, err := client.Jobs().Register(job1, nil) - require.NoError(t, err) + must.NoError(t, err) + code := waitForSuccess(ui, client, fullId, t, resp.EvalID) - require.Zero(t, code, "status code not zero") + must.Zero(t, code) // get an alloc id allocId1 := "" @@ -128,16 +115,24 @@ func TestAllocExecCommand_Fails(t *testing.T) { allocId1 = allocs[0].ID } } - require.NotEmpty(t, allocId1, "unable to find allocation") + must.NotEq(t, "", allocId1) // by alloc - require.Equal(t, 1, cmd.Run([]string{"-address=" + url, "-task=nonexistenttask1", allocId1, "/bin/bash"})) - require.Contains(t, ui.ErrorWriter.String(), "Could not find task named: nonexistenttask1") + code = cmd.Run([]string{"-address=" + url, "-task=nonexistenttask1", allocId1, "/bin/bash"}) + must.One(t, code) + + out := ui.ErrorWriter.String() + must.StrContains(t, out, "Could not find task named: nonexistenttask1") + ui.ErrorWriter.Reset() // by jobID - require.Equal(t, 1, cmd.Run([]string{"-address=" + url, "-task=nonexistenttask2", "-job", jobID, "/bin/bash"})) - require.Contains(t, ui.ErrorWriter.String(), "Could not find task named: nonexistenttask2") + code = cmd.Run([]string{"-address=" + url, "-task=nonexistenttask2", "-job", jobID, "/bin/bash"}) + must.One(t, code) + + out = ui.ErrorWriter.String() + must.StrContains(t, out, "Could not find task named: nonexistenttask2") + ui.ErrorWriter.Reset() }) @@ -145,10 +140,9 @@ func TestAllocExecCommand_Fails(t *testing.T) { func TestAllocExecCommand_AutocompleteArgs(t *testing.T) { ci.Parallel(t) - assert := assert.New(t) srv, _, url := testServer(t, true, nil) - defer srv.Shutdown() + defer stopTestAgent(srv) ui := cli.NewMockUi() cmd := &AllocExecCommand{Meta: Meta{Ui: ui, flagAddress: url}} @@ -156,39 +150,24 @@ func TestAllocExecCommand_AutocompleteArgs(t *testing.T) { // Create a fake alloc state := srv.Agent.Server().State() a := mock.Alloc() - assert.Nil(state.UpsertAllocs(structs.MsgTypeTestSetup, 1000, []*structs.Allocation{a})) + must.NoError(t, state.UpsertAllocs(structs.MsgTypeTestSetup, 1000, []*structs.Allocation{a})) prefix := a.ID[:5] args := complete.Args{Last: prefix} predictor := cmd.AutocompleteArgs() res := predictor.Predict(args) - assert.Equal(1, len(res)) - assert.Equal(a.ID, res[0]) + must.Len(t, 1, res) + must.Eq(t, a.ID, res[0]) } func TestAllocExecCommand_Run(t *testing.T) { ci.Parallel(t) srv, client, url := testServer(t, true, nil) - defer srv.Shutdown() + defer stopTestAgent(srv) // Wait for a node to be ready - testutil.WaitForResult(func() (bool, error) { - nodes, _, err := client.Nodes().List(nil) - if err != nil { - return false, err - } - - for _, node := range nodes { - if _, ok := node.Drivers["mock_driver"]; ok && - node.Status == structs.NodeStatusReady { - return true, nil - } - } - return false, fmt.Errorf("no ready nodes") - }, func(err error) { - require.NoError(t, err) - }) + waitForNodes(t, client) jobID := uuid.Generate() job := testJob(jobID) @@ -202,11 +181,11 @@ func TestAllocExecCommand_Run(t *testing.T) { }, } resp, _, err := client.Jobs().Register(job, nil) - require.NoError(t, err) + must.NoError(t, err) evalUi := cli.NewMockUi() code := waitForSuccess(evalUi, client, fullId, t, resp.EvalID) - require.Equal(t, 0, code, "failed to get status - output: %v", evalUi.ErrorWriter.String()) + must.Zero(t, code) allocId := "" @@ -227,10 +206,7 @@ func TestAllocExecCommand_Run(t *testing.T) { allocId = alloc.ID return true, nil - }, func(err error) { - require.NoError(t, err) - - }) + }, func(err error) { must.NoError(t, err) }) cases := []struct { name string @@ -271,9 +247,9 @@ func TestAllocExecCommand_Run(t *testing.T) { } code = cmd.Run([]string{"-address=" + url, allocId, c.command}) - assert.Equal(t, c.exitCode, code) - assert.Equal(t, c.stdout, strings.TrimSpace(stdout.String())) - assert.Equal(t, c.stderr, strings.TrimSpace(stderr.String())) + must.Eq(t, c.exitCode, code) + must.Eq(t, c.stdout, strings.TrimSpace(stdout.String())) + must.Eq(t, c.stderr, strings.TrimSpace(stderr.String())) }) t.Run("by job: "+c.name, func(t *testing.T) { ui := cli.NewMockUi() @@ -287,9 +263,9 @@ func TestAllocExecCommand_Run(t *testing.T) { } code = cmd.Run([]string{"-address=" + url, "-job", jobID, c.command}) - assert.Equal(t, c.exitCode, code) - assert.Equal(t, c.stdout, strings.TrimSpace(stdout.String())) - assert.Equal(t, c.stderr, strings.TrimSpace(stderr.String())) + must.Eq(t, c.exitCode, code) + must.Eq(t, c.stdout, strings.TrimSpace(stdout.String())) + must.Eq(t, c.stderr, strings.TrimSpace(stderr.String())) }) } } diff --git a/command/alloc_fs_test.go b/command/alloc_fs_test.go index 967c3dd11..84fd1b917 100644 --- a/command/alloc_fs_test.go +++ b/command/alloc_fs_test.go @@ -1,7 +1,6 @@ package command import ( - "strings" "testing" "github.com/hashicorp/nomad/ci" @@ -9,7 +8,7 @@ import ( "github.com/hashicorp/nomad/nomad/structs" "github.com/mitchellh/cli" "github.com/posener/complete" - "github.com/stretchr/testify/assert" + "github.com/shoenig/test/must" ) func TestFSCommand_Implements(t *testing.T) { @@ -20,80 +19,78 @@ func TestFSCommand_Implements(t *testing.T) { func TestFSCommand_Fails(t *testing.T) { ci.Parallel(t) srv, _, url := testServer(t, false, nil) - defer srv.Shutdown() + defer stopTestAgent(srv) ui := cli.NewMockUi() cmd := &AllocFSCommand{Meta: Meta{Ui: ui}} // Fails on lack of job ID - if code := cmd.Run([]string{"-job"}); code != 1 { - t.Fatalf("expected exit code 1, got: %d", code) - } - if out := ui.ErrorWriter.String(); !strings.Contains(out, "job ID is required") { - t.Fatalf("expected help output, got: %s", out) - } + code := cmd.Run([]string{"-job"}) + must.One(t, code) + + out := ui.ErrorWriter.String() + must.StrContains(t, out, "job ID is required") + ui.ErrorWriter.Reset() // Fails on lack of allocation ID - if code := cmd.Run([]string{}); code != 1 { - t.Fatalf("expected exit code 1, got: %d", code) - } - if out := ui.ErrorWriter.String(); !strings.Contains(out, "allocation ID is required") { - t.Fatalf("expected help output, got: %s", out) - } + code = cmd.Run([]string{}) + must.One(t, code) + + out = ui.ErrorWriter.String() + must.StrContains(t, out, "allocation ID is required") + ui.ErrorWriter.Reset() // Fails on misuse - if code := cmd.Run([]string{"some", "bad", "args"}); code != 1 { - t.Fatalf("expected exit code 1, got: %d", code) - } - if out := ui.ErrorWriter.String(); !strings.Contains(out, commandErrorText(cmd)) { - t.Fatalf("expected help output, got: %s", out) - } + code = cmd.Run([]string{"some", "bad", "args"}) + must.One(t, code) + + out = ui.ErrorWriter.String() + must.StrContains(t, out, commandErrorText(cmd)) + ui.ErrorWriter.Reset() // Fails on connection failure - if code := cmd.Run([]string{"-address=nope", "foobar"}); code != 1 { - t.Fatalf("expected exit code 1, got: %d", code) - } - if out := ui.ErrorWriter.String(); !strings.Contains(out, "Error querying allocation") { - t.Fatalf("expected failed query error, got: %s", out) - } + code = cmd.Run([]string{"-address=nope", "foobar"}) + must.One(t, code) + + out = ui.ErrorWriter.String() + must.StrContains(t, out, "Error querying allocation") + ui.ErrorWriter.Reset() // Fails on missing alloc - if code := cmd.Run([]string{"-address=" + url, "26470238-5CF2-438F-8772-DC67CFB0705C"}); code != 1 { - t.Fatalf("expected exit 1, got: %d", code) - } - if out := ui.ErrorWriter.String(); !strings.Contains(out, "No allocation(s) with prefix or id") { - t.Fatalf("expected not found error, got: %s", out) - } + code = cmd.Run([]string{"-address=" + url, "26470238-5CF2-438F-8772-DC67CFB0705C"}) + must.One(t, code) + + out = ui.ErrorWriter.String() + must.StrContains(t, out, "No allocation(s) with prefix or id") + ui.ErrorWriter.Reset() // Fail on identifier with too few characters - if code := cmd.Run([]string{"-address=" + url, "2"}); code != 1 { - t.Fatalf("expected exit 1, got: %d", code) - } - if out := ui.ErrorWriter.String(); !strings.Contains(out, "must contain at least two characters.") { - t.Fatalf("expected too few characters error, got: %s", out) - } + code = cmd.Run([]string{"-address=" + url, "2"}) + must.One(t, code) + + out = ui.ErrorWriter.String() + must.StrContains(t, out, "must contain at least two characters.") + ui.ErrorWriter.Reset() // Identifiers with uneven length should produce a query result - if code := cmd.Run([]string{"-address=" + url, "123"}); code != 1 { - t.Fatalf("expected exit 1, got: %d", code) - } - if out := ui.ErrorWriter.String(); !strings.Contains(out, "No allocation(s) with prefix or id") { - t.Fatalf("expected not found error, got: %s", out) - } + code = cmd.Run([]string{"-address=" + url, "123"}) + must.One(t, code) + + out = ui.ErrorWriter.String() + must.StrContains(t, out, "No allocation(s) with prefix or id") } func TestFSCommand_AutocompleteArgs(t *testing.T) { ci.Parallel(t) - assert := assert.New(t) srv, _, url := testServer(t, true, nil) - defer srv.Shutdown() + defer stopTestAgent(srv) ui := cli.NewMockUi() cmd := &AllocFSCommand{Meta: Meta{Ui: ui, flagAddress: url}} @@ -101,13 +98,13 @@ func TestFSCommand_AutocompleteArgs(t *testing.T) { // Create a fake alloc state := srv.Agent.Server().State() a := mock.Alloc() - assert.Nil(state.UpsertAllocs(structs.MsgTypeTestSetup, 1000, []*structs.Allocation{a})) + must.NoError(t, state.UpsertAllocs(structs.MsgTypeTestSetup, 1000, []*structs.Allocation{a})) prefix := a.ID[:5] args := complete.Args{Last: prefix} predictor := cmd.AutocompleteArgs() res := predictor.Predict(args) - assert.Equal(1, len(res)) - assert.Equal(a.ID, res[0]) + must.Len(t, 1, res) + must.Eq(t, a.ID, res[0]) } diff --git a/command/alloc_logs_test.go b/command/alloc_logs_test.go index 5698433fd..f1d18d224 100644 --- a/command/alloc_logs_test.go +++ b/command/alloc_logs_test.go @@ -1,7 +1,6 @@ package command import ( - "strings" "testing" "github.com/hashicorp/nomad/ci" @@ -9,7 +8,7 @@ import ( "github.com/hashicorp/nomad/nomad/structs" "github.com/mitchellh/cli" "github.com/posener/complete" - "github.com/stretchr/testify/assert" + "github.com/shoenig/test/must" ) func TestLogsCommand_Implements(t *testing.T) { @@ -20,62 +19,60 @@ func TestLogsCommand_Implements(t *testing.T) { func TestLogsCommand_Fails(t *testing.T) { ci.Parallel(t) srv, _, url := testServer(t, false, nil) - defer srv.Shutdown() + defer stopTestAgent(srv) ui := cli.NewMockUi() cmd := &AllocLogsCommand{Meta: Meta{Ui: ui}} // Fails on misuse - if code := cmd.Run([]string{"some", "bad", "args"}); code != 1 { - t.Fatalf("expected exit code 1, got: %d", code) - } - if out := ui.ErrorWriter.String(); !strings.Contains(out, commandErrorText(cmd)) { - t.Fatalf("expected help output, got: %s", out) - } + code := cmd.Run([]string{"some", "bad", "args"}) + must.One(t, code) + + out := ui.ErrorWriter.String() + must.StrContains(t, out, commandErrorText(cmd)) + ui.ErrorWriter.Reset() // Fails on connection failure - if code := cmd.Run([]string{"-address=nope", "foobar"}); code != 1 { - t.Fatalf("expected exit code 1, got: %d", code) - } - if out := ui.ErrorWriter.String(); !strings.Contains(out, "Error querying allocation") { - t.Fatalf("expected failed query error, got: %s", out) - } + code = cmd.Run([]string{"-address=nope", "foobar"}) + must.One(t, code) + + out = ui.ErrorWriter.String() + must.StrContains(t, out, "Error querying allocation") + ui.ErrorWriter.Reset() // Fails on missing alloc - if code := cmd.Run([]string{"-address=" + url, "26470238-5CF2-438F-8772-DC67CFB0705C"}); code != 1 { - t.Fatalf("expected exit 1, got: %d", code) - } - if out := ui.ErrorWriter.String(); !strings.Contains(out, "No allocation(s) with prefix or id") { - t.Fatalf("expected not found error, got: %s", out) - } + code = cmd.Run([]string{"-address=" + url, "26470238-5CF2-438F-8772-DC67CFB0705C"}) + must.One(t, code) + + out = ui.ErrorWriter.String() + must.StrContains(t, out, "No allocation(s) with prefix or id") + ui.ErrorWriter.Reset() // Fail on identifier with too few characters - if code := cmd.Run([]string{"-address=" + url, "2"}); code != 1 { - t.Fatalf("expected exit 1, got: %d", code) - } - if out := ui.ErrorWriter.String(); !strings.Contains(out, "must contain at least two characters.") { - t.Fatalf("expected too few characters error, got: %s", out) - } + code = cmd.Run([]string{"-address=" + url, "2"}) + must.One(t, code) + + out = ui.ErrorWriter.String() + must.StrContains(t, out, "must contain at least two characters.") + ui.ErrorWriter.Reset() // Identifiers with uneven length should produce a query result - if code := cmd.Run([]string{"-address=" + url, "123"}); code != 1 { - t.Fatalf("expected exit 1, got: %d", code) - } - if out := ui.ErrorWriter.String(); !strings.Contains(out, "No allocation(s) with prefix or id") { - t.Fatalf("expected not found error, got: %s", out) - } + code = cmd.Run([]string{"-address=" + url, "123"}) + must.One(t, code) + + out = ui.ErrorWriter.String() + must.StrContains(t, out, "No allocation(s) with prefix or id") } func TestLogsCommand_AutocompleteArgs(t *testing.T) { ci.Parallel(t) - assert := assert.New(t) srv, _, url := testServer(t, true, nil) - defer srv.Shutdown() + defer stopTestAgent(srv) ui := cli.NewMockUi() cmd := &AllocLogsCommand{Meta: Meta{Ui: ui, flagAddress: url}} @@ -83,13 +80,13 @@ func TestLogsCommand_AutocompleteArgs(t *testing.T) { // Create a fake alloc state := srv.Agent.Server().State() a := mock.Alloc() - assert.Nil(state.UpsertAllocs(structs.MsgTypeTestSetup, 1000, []*structs.Allocation{a})) + must.NoError(t, state.UpsertAllocs(structs.MsgTypeTestSetup, 1000, []*structs.Allocation{a})) prefix := a.ID[:5] args := complete.Args{Last: prefix} predictor := cmd.AutocompleteArgs() res := predictor.Predict(args) - assert.Equal(1, len(res)) - assert.Equal(a.ID, res[0]) + must.Len(t, 1, res) + must.Eq(t, a.ID, res[0]) } diff --git a/command/alloc_restart_test.go b/command/alloc_restart_test.go index fb1e88762..b76985597 100644 --- a/command/alloc_restart_test.go +++ b/command/alloc_restart_test.go @@ -1,18 +1,14 @@ package command import ( - "fmt" "testing" - "github.com/hashicorp/nomad/api" "github.com/hashicorp/nomad/ci" "github.com/hashicorp/nomad/nomad/mock" "github.com/hashicorp/nomad/nomad/structs" - "github.com/hashicorp/nomad/testutil" "github.com/mitchellh/cli" "github.com/posener/complete" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/shoenig/test/must" ) func TestAllocRestartCommand_Implements(t *testing.T) { @@ -23,61 +19,67 @@ func TestAllocRestartCommand_Fails(t *testing.T) { ci.Parallel(t) srv, client, url := testServer(t, true, nil) - defer srv.Shutdown() + defer stopTestAgent(srv) - require := require.New(t) ui := cli.NewMockUi() cmd := &AllocRestartCommand{Meta: Meta{Ui: ui}} // Fails on misuse - require.Equal(cmd.Run([]string{"some", "garbage", "args"}), 1, "Expected failure") - require.Contains(ui.ErrorWriter.String(), commandErrorText(cmd), "Expected help output") + code := cmd.Run([]string{"some", "garbage", "args"}) + must.One(t, code) + + out := ui.ErrorWriter.String() + must.StrContains(t, out, commandErrorText(cmd)) + ui.ErrorWriter.Reset() // Fails on connection failure - require.Equal(cmd.Run([]string{"-address=nope", "foobar"}), 1, "expected failure") - require.Contains(ui.ErrorWriter.String(), "Error querying allocation") + code = cmd.Run([]string{"-address=nope", "foobar"}) + must.One(t, code) + + out = ui.ErrorWriter.String() + must.StrContains(t, out, "Error querying allocation") + ui.ErrorWriter.Reset() // Fails on missing alloc - require.Equal(cmd.Run([]string{"-address=" + url, "26470238-5CF2-438F-8772-DC67CFB0705C"}), 1) - require.Contains(ui.ErrorWriter.String(), "No allocation(s) with prefix or id") + code = cmd.Run([]string{"-address=" + url, "26470238-5CF2-438F-8772-DC67CFB0705C"}) + must.One(t, code) + + out = ui.ErrorWriter.String() + must.StrContains(t, out, "No allocation(s) with prefix or id") + ui.ErrorWriter.Reset() // Fail on identifier with too few characters - require.Equal(cmd.Run([]string{"-address=" + url, "2"}), 1) - require.Contains(ui.ErrorWriter.String(), "must contain at least two characters") + code = cmd.Run([]string{"-address=" + url, "2"}) + must.One(t, code) + + out = ui.ErrorWriter.String() + must.StrContains(t, out, "must contain at least two characters") + ui.ErrorWriter.Reset() // Identifiers with uneven length should produce a query result - require.Equal(cmd.Run([]string{"-address=" + url, "123"}), 1) - require.Contains(ui.ErrorWriter.String(), "No allocation(s) with prefix or id") + code = cmd.Run([]string{"-address=" + url, "123"}) + must.One(t, code) + + out = ui.ErrorWriter.String() + must.StrContains(t, out, "No allocation(s) with prefix or id") + ui.ErrorWriter.Reset() // Wait for a node to be ready - testutil.WaitForResult(func() (bool, error) { - nodes, _, err := client.Nodes().List(nil) - if err != nil { - return false, err - } - for _, node := range nodes { - if _, ok := node.Drivers["mock_driver"]; ok && - node.Status == structs.NodeStatusReady { - return true, nil - } - } - return false, fmt.Errorf("no ready nodes") - }, func(err error) { - t.Fatalf("err: %v", err) - }) + waitForNodes(t, client) jobID := "job1_sfx" job1 := testJob(jobID) resp, _, err := client.Jobs().Register(job1, nil) - require.NoError(err) - if code := waitForSuccess(ui, client, fullId, t, resp.EvalID); code != 0 { - t.Fatalf("status code non zero saw %d", code) - } + must.NoError(t, err) + + code = waitForSuccess(ui, client, fullId, t, resp.EvalID) + must.Zero(t, code) + // get an alloc id allocId1 := "" if allocs, _, err := client.Jobs().Allocations(jobID, false, nil); err == nil { @@ -85,11 +87,15 @@ func TestAllocRestartCommand_Fails(t *testing.T) { allocId1 = allocs[0].ID } } - require.NotEmpty(allocId1, "unable to find allocation") + must.NotEq(t, "", allocId1) // Fails on not found task - require.Equal(cmd.Run([]string{"-address=" + url, allocId1, "fooooobarrr"}), 1) - require.Contains(ui.ErrorWriter.String(), "Could not find task named") + code = cmd.Run([]string{"-address=" + url, allocId1, "fooooobarrr"}) + must.One(t, code) + + out = ui.ErrorWriter.String() + must.StrContains(t, out, "Could not find task named") + ui.ErrorWriter.Reset() } @@ -97,26 +103,10 @@ func TestAllocRestartCommand_Run(t *testing.T) { ci.Parallel(t) srv, client, url := testServer(t, true, nil) - defer srv.Shutdown() - - require := require.New(t) + defer stopTestAgent(srv) // Wait for a node to be ready - testutil.WaitForResult(func() (bool, error) { - nodes, _, err := client.Nodes().List(nil) - if err != nil { - return false, err - } - for _, node := range nodes { - if _, ok := node.Drivers["mock_driver"]; ok && - node.Status == structs.NodeStatusReady { - return true, nil - } - } - return false, fmt.Errorf("no ready nodes") - }, func(err error) { - t.Fatalf("err: %v", err) - }) + waitForNodes(t, client) ui := cli.NewMockUi() cmd := &AllocRestartCommand{Meta: Meta{Ui: ui}} @@ -124,34 +114,25 @@ func TestAllocRestartCommand_Run(t *testing.T) { jobID := "job1_sfx" job1 := testJob(jobID) resp, _, err := client.Jobs().Register(job1, nil) - require.NoError(err) - if code := waitForSuccess(ui, client, fullId, t, resp.EvalID); code != 0 { - t.Fatalf("status code non zero saw %d", code) - } + must.NoError(t, err) + + code := waitForSuccess(ui, client, fullId, t, resp.EvalID) + must.Zero(t, code) + // get an alloc id - allocId1 := "" + allocID := "" if allocs, _, err := client.Jobs().Allocations(jobID, false, nil); err == nil { if len(allocs) > 0 { - allocId1 = allocs[0].ID + allocID = allocs[0].ID } } - require.NotEmpty(allocId1, "unable to find allocation") + must.NotEq(t, "", allocID) // Wait for alloc to be running - testutil.WaitForResult(func() (bool, error) { - alloc, _, err := client.Allocations().Info(allocId1, nil) - if err != nil { - return false, err - } - if alloc.ClientStatus == api.AllocClientStatusRunning { - return true, nil - } - return false, fmt.Errorf("alloc is not running, is: %s", alloc.ClientStatus) - }, func(err error) { - t.Fatalf("err: %v", err) - }) + waitForAllocRunning(t, client, allocID) - require.Equal(cmd.Run([]string{"-address=" + url, allocId1}), 0, "expected successful exit code") + code = cmd.Run([]string{"-address=" + url, allocID}) + must.Zero(t, code) ui.OutputWriter.Reset() } @@ -159,10 +140,8 @@ func TestAllocRestartCommand_Run(t *testing.T) { func TestAllocRestartCommand_AutocompleteArgs(t *testing.T) { ci.Parallel(t) - assert := assert.New(t) - srv, _, url := testServer(t, true, nil) - defer srv.Shutdown() + defer stopTestAgent(srv) ui := cli.NewMockUi() cmd := &AllocRestartCommand{Meta: Meta{Ui: ui, flagAddress: url}} @@ -170,13 +149,13 @@ func TestAllocRestartCommand_AutocompleteArgs(t *testing.T) { // Create a fake alloc state := srv.Agent.Server().State() a := mock.Alloc() - assert.Nil(state.UpsertAllocs(structs.MsgTypeTestSetup, 1000, []*structs.Allocation{a})) + must.NoError(t, state.UpsertAllocs(structs.MsgTypeTestSetup, 1000, []*structs.Allocation{a})) prefix := a.ID[:5] args := complete.Args{Last: prefix} predictor := cmd.AutocompleteArgs() res := predictor.Predict(args) - assert.Equal(1, len(res)) - assert.Equal(a.ID, res[0]) + must.Len(t, 1, res) + must.Eq(t, a.ID, res[0]) } diff --git a/command/alloc_signal_test.go b/command/alloc_signal_test.go index 46e18d146..4d9a0d730 100644 --- a/command/alloc_signal_test.go +++ b/command/alloc_signal_test.go @@ -1,18 +1,14 @@ package command import ( - "fmt" "testing" - "github.com/hashicorp/nomad/api" "github.com/hashicorp/nomad/ci" "github.com/hashicorp/nomad/nomad/mock" "github.com/hashicorp/nomad/nomad/structs" - "github.com/hashicorp/nomad/testutil" "github.com/mitchellh/cli" "github.com/posener/complete" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/shoenig/test/must" ) func TestAllocSignalCommand_Implements(t *testing.T) { @@ -23,47 +19,62 @@ func TestAllocSignalCommand_Implements(t *testing.T) { func TestAllocSignalCommand_Fails(t *testing.T) { ci.Parallel(t) srv, _, url := testServer(t, false, nil) - defer srv.Shutdown() - - require := require.New(t) + defer stopTestAgent(srv) ui := cli.NewMockUi() cmd := &AllocSignalCommand{Meta: Meta{Ui: ui}} // Fails on lack of alloc ID - require.Equal(1, cmd.Run([]string{})) - require.Contains(ui.ErrorWriter.String(), "This command takes up to two arguments") + code := cmd.Run([]string{}) + must.One(t, code) + + out := ui.ErrorWriter.String() + must.StrContains(t, out, "This command takes up to two arguments") + ui.ErrorWriter.Reset() // Fails on misuse - require.Equal(1, cmd.Run([]string{"some", "bad", "args"})) - require.Contains(ui.ErrorWriter.String(), "This command takes up to two arguments") + code = cmd.Run([]string{"some", "bad", "args"}) + must.One(t, code) + + out = ui.ErrorWriter.String() + must.StrContains(t, out, "This command takes up to two arguments") + ui.ErrorWriter.Reset() // Fails on connection failure - require.Equal(1, cmd.Run([]string{"-address=nope", "foobar"})) - require.Contains(ui.ErrorWriter.String(), "Error querying allocation") + code = cmd.Run([]string{"-address=nope", "foobar"}) + must.One(t, code) + + out = ui.ErrorWriter.String() + must.StrContains(t, out, "Error querying allocation") + ui.ErrorWriter.Reset() // Fails on missing alloc - code := cmd.Run([]string{"-address=" + url, "26470238-5CF2-438F-8772-DC67CFB0705C"}) - require.Equal(1, code) - require.Contains(ui.ErrorWriter.String(), "No allocation(s) with prefix or id") + code = cmd.Run([]string{"-address=" + url, "26470238-5CF2-438F-8772-DC67CFB0705C"}) + must.One(t, code) + + out = ui.ErrorWriter.String() + must.StrContains(t, out, "No allocation(s) with prefix or id") + ui.ErrorWriter.Reset() // Fail on identifier with too few characters - require.Equal(1, cmd.Run([]string{"-address=" + url, "2"})) - require.Contains(ui.ErrorWriter.String(), "must contain at least two characters.") + code = cmd.Run([]string{"-address=" + url, "2"}) + must.One(t, code) + + out = ui.ErrorWriter.String() + must.StrContains(t, out, "must contain at least two characters.") + ui.ErrorWriter.Reset() } func TestAllocSignalCommand_AutocompleteArgs(t *testing.T) { ci.Parallel(t) - assert := assert.New(t) - srv, _, url := testServer(t, true, nil) - defer srv.Shutdown() + defer stopTestAgent(srv) ui := cli.NewMockUi() cmd := &AllocSignalCommand{Meta: Meta{Ui: ui, flagAddress: url}} @@ -71,7 +82,7 @@ func TestAllocSignalCommand_AutocompleteArgs(t *testing.T) { // Create a fake alloc state := srv.Agent.Server().State() a := mock.Alloc() - assert.Nil(state.UpsertAllocs(structs.MsgTypeTestSetup, 1000, []*structs.Allocation{a})) + must.NoError(t, state.UpsertAllocs(structs.MsgTypeTestSetup, 1000, []*structs.Allocation{a})) prefix := a.ID[:5] args := complete.Args{All: []string{"signal", prefix}, Last: prefix} @@ -79,34 +90,18 @@ func TestAllocSignalCommand_AutocompleteArgs(t *testing.T) { // Match Allocs res := predictor.Predict(args) - assert.Equal(1, len(res)) - assert.Equal(a.ID, res[0]) + must.Len(t, 1, res) + must.Eq(t, a.ID, res[0]) } func TestAllocSignalCommand_Run(t *testing.T) { ci.Parallel(t) srv, client, url := testServer(t, true, nil) - defer srv.Shutdown() - - require := require.New(t) + defer stopTestAgent(srv) // Wait for a node to be ready - testutil.WaitForResult(func() (bool, error) { - nodes, _, err := client.Nodes().List(nil) - if err != nil { - return false, err - } - for _, node := range nodes { - if _, ok := node.Drivers["mock_driver"]; ok && - node.Status == structs.NodeStatusReady { - return true, nil - } - } - return false, fmt.Errorf("no ready nodes") - }, func(err error) { - t.Fatalf("err: %v", err) - }) + waitForNodes(t, client) ui := cli.NewMockUi() cmd := &AllocSignalCommand{Meta: Meta{Ui: ui}} @@ -114,34 +109,25 @@ func TestAllocSignalCommand_Run(t *testing.T) { jobID := "job1_sfx" job1 := testJob(jobID) resp, _, err := client.Jobs().Register(job1, nil) - require.NoError(err) - if code := waitForSuccess(ui, client, fullId, t, resp.EvalID); code != 0 { - t.Fatalf("status code non zero saw %d", code) - } + must.NoError(t, err) + + code := waitForSuccess(ui, client, fullId, t, resp.EvalID) + must.Zero(t, code) + // get an alloc id - allocId1 := "" + allocID := "" if allocs, _, err := client.Jobs().Allocations(jobID, false, nil); err == nil { if len(allocs) > 0 { - allocId1 = allocs[0].ID + allocID = allocs[0].ID } } - require.NotEmpty(allocId1, "unable to find allocation") + must.NotEq(t, "", allocID) // Wait for alloc to be running - testutil.WaitForResult(func() (bool, error) { - alloc, _, err := client.Allocations().Info(allocId1, nil) - if err != nil { - return false, err - } - if alloc.ClientStatus == api.AllocClientStatusRunning { - return true, nil - } - return false, fmt.Errorf("alloc is not running, is: %s", alloc.ClientStatus) - }, func(err error) { - t.Fatalf("err: %v", err) - }) + waitForAllocRunning(t, client, allocID) - require.Equal(cmd.Run([]string{"-address=" + url, allocId1}), 0, "expected successful exit code") + code = cmd.Run([]string{"-address=" + url, allocID}) + must.Zero(t, code) ui.OutputWriter.Reset() } diff --git a/command/alloc_status_test.go b/command/alloc_status_test.go index eb9bd69fe..18d594bb7 100644 --- a/command/alloc_status_test.go +++ b/command/alloc_status_test.go @@ -3,7 +3,6 @@ package command import ( "fmt" "regexp" - "strings" "testing" "time" @@ -15,7 +14,6 @@ import ( "github.com/mitchellh/cli" "github.com/posener/complete" "github.com/shoenig/test/must" - "github.com/stretchr/testify/require" ) func TestAllocStatusCommand_Implements(t *testing.T) { @@ -32,61 +30,61 @@ func TestAllocStatusCommand_Fails(t *testing.T) { cmd := &AllocStatusCommand{Meta: Meta{Ui: ui}} // Fails on misuse - if code := cmd.Run([]string{"some", "bad", "args"}); code != 1 { - t.Fatalf("expected exit code 1, got: %d", code) - } - if out := ui.ErrorWriter.String(); !strings.Contains(out, commandErrorText(cmd)) { - t.Fatalf("expected help output, got: %s", out) - } + code := cmd.Run([]string{"some", "bad", "args"}) + must.One(t, code) + + out := ui.ErrorWriter.String() + must.StrContains(t, out, commandErrorText(cmd)) + ui.ErrorWriter.Reset() // Fails on connection failure - if code := cmd.Run([]string{"-address=nope", "foobar"}); code != 1 { - t.Fatalf("expected exit code 1, got: %d", code) - } - if out := ui.ErrorWriter.String(); !strings.Contains(out, "Error querying allocation") { - t.Fatalf("expected failed query error, got: %s", out) - } + code = cmd.Run([]string{"-address=nope", "foobar"}) + must.One(t, code) + + out = ui.ErrorWriter.String() + must.StrContains(t, out, "Error querying allocation") + ui.ErrorWriter.Reset() // Fails on missing alloc - if code := cmd.Run([]string{"-address=" + url, "26470238-5CF2-438F-8772-DC67CFB0705C"}); code != 1 { - t.Fatalf("expected exit 1, got: %d", code) - } - if out := ui.ErrorWriter.String(); !strings.Contains(out, "No allocation(s) with prefix or id") { - t.Fatalf("expected not found error, got: %s", out) - } + code = cmd.Run([]string{"-address=" + url, "26470238-5CF2-438F-8772-DC67CFB0705C"}) + must.One(t, code) + + out = ui.ErrorWriter.String() + must.StrContains(t, out, "No allocation(s) with prefix or id") + ui.ErrorWriter.Reset() // Fail on identifier with too few characters - if code := cmd.Run([]string{"-address=" + url, "2"}); code != 1 { - t.Fatalf("expected exit 1, got: %d", code) - } - if out := ui.ErrorWriter.String(); !strings.Contains(out, "must contain at least two characters.") { - t.Fatalf("expected too few characters error, got: %s", out) - } + code = cmd.Run([]string{"-address=" + url, "2"}) + must.One(t, code) + + out = ui.ErrorWriter.String() + must.StrContains(t, out, "must contain at least two characters.") + ui.ErrorWriter.Reset() // Identifiers with uneven length should produce a query result - if code := cmd.Run([]string{"-address=" + url, "123"}); code != 1 { - t.Fatalf("expected exit 1, got: %d", code) - } - if out := ui.ErrorWriter.String(); !strings.Contains(out, "No allocation(s) with prefix or id") { - t.Fatalf("expected not found error, got: %s", out) - } + code = cmd.Run([]string{"-address=" + url, "123"}) + must.One(t, code) + + out = ui.ErrorWriter.String() + must.StrContains(t, out, "No allocation(s) with prefix or id") + ui.ErrorWriter.Reset() // Failed on both -json and -t options are specified - if code := cmd.Run([]string{"-address=" + url, "-json", "-t", "{{.ID}}"}); code != 1 { - t.Fatalf("expected exit 1, got: %d", code) - } - if out := ui.ErrorWriter.String(); !strings.Contains(out, "Both json and template formatting are not allowed") { - t.Fatalf("expected getting formatter error, got: %s", out) - } + code = cmd.Run([]string{"-address=" + url, "-json", "-t", "{{.ID}}"}) + must.One(t, code) + + out = ui.ErrorWriter.String() + must.StrContains(t, out, "Both json and template formatting are not allowed") } func TestAllocStatusCommand_LifecycleInfo(t *testing.T) { ci.Parallel(t) + srv, client, url := testServer(t, true, nil) defer stopTestAgent(srv) @@ -122,16 +120,15 @@ func TestAllocStatusCommand_LifecycleInfo(t *testing.T) { "prestart_sidecar": {State: "running"}, } - require.Nil(t, state.UpsertAllocs(structs.MsgTypeTestSetup, 1000, []*structs.Allocation{a})) + must.NoError(t, state.UpsertAllocs(structs.MsgTypeTestSetup, 1000, []*structs.Allocation{a})) + + code := cmd.Run([]string{"-address=" + url, a.ID}) + must.Zero(t, code) - if code := cmd.Run([]string{"-address=" + url, a.ID}); code != 0 { - t.Fatalf("expected exit 0, got: %d", code) - } out := ui.OutputWriter.String() - - require.Contains(t, out, `Task "init_task" (prestart) is "running"`) - require.Contains(t, out, `Task "prestart_sidecar" (prestart sidecar) is "running"`) - require.Contains(t, out, `Task "web" is "pending"`) + must.StrContains(t, out, `Task "init_task" (prestart) is "running"`) + must.StrContains(t, out, `Task "prestart_sidecar" (prestart sidecar) is "running"`) + must.StrContains(t, out, `Task "web" is "pending"`) } func TestAllocStatusCommand_Run(t *testing.T) { @@ -147,73 +144,56 @@ func TestAllocStatusCommand_Run(t *testing.T) { jobID := "job1_sfx" job1 := testJob(jobID) resp, _, err := client.Jobs().Register(job1, nil) - if err != nil { - t.Fatalf("err: %s", err) - } - if code := waitForSuccess(ui, client, fullId, t, resp.EvalID); code != 0 { - t.Fatalf("status code non zero saw %d", code) - } + must.NoError(t, err) + + code := waitForSuccess(ui, client, fullId, t, resp.EvalID) + must.Zero(t, code) + // get an alloc id - allocId1 := "" + allocID := "" nodeName := "" if allocs, _, err := client.Jobs().Allocations(jobID, false, nil); err == nil { if len(allocs) > 0 { - allocId1 = allocs[0].ID + allocID = allocs[0].ID nodeName = allocs[0].NodeName } } - if allocId1 == "" { - t.Fatal("unable to find an allocation") - } + must.NotEq(t, "", allocID) + + code = cmd.Run([]string{"-address=" + url, allocID}) + must.Zero(t, code) - if code := cmd.Run([]string{"-address=" + url, allocId1}); code != 0 { - t.Fatalf("expected exit 0, got: %d", code) - } out := ui.OutputWriter.String() - if !strings.Contains(out, "Created") { - t.Fatalf("expected to have 'Created' but saw: %s", out) - } - - if !strings.Contains(out, "Modified") { - t.Fatalf("expected to have 'Modified' but saw: %s", out) - } + must.StrContains(t, out, "Created") + must.StrContains(t, out, "Modified") nodeNameRegexpStr := fmt.Sprintf(`\nNode Name\s+= %s\n`, regexp.QuoteMeta(nodeName)) - require.Regexp(t, regexp.MustCompile(nodeNameRegexpStr), out) + must.RegexMatch(t, regexp.MustCompile(nodeNameRegexpStr), out) ui.OutputWriter.Reset() - if code := cmd.Run([]string{"-address=" + url, "-verbose", allocId1}); code != 0 { - t.Fatalf("expected exit 0, got: %d", code) - } + code = cmd.Run([]string{"-address=" + url, "-verbose", allocID}) + must.Zero(t, code) + out = ui.OutputWriter.String() - if !strings.Contains(out, allocId1) { - t.Fatal("expected to find alloc id in output") - } - if !strings.Contains(out, "Created") { - t.Fatalf("expected to have 'Created' but saw: %s", out) - } + must.StrContains(t, out, allocID) + must.StrContains(t, out, "Created") + ui.OutputWriter.Reset() // Try the query with an even prefix that includes the hyphen - if code := cmd.Run([]string{"-address=" + url, allocId1[:13]}); code != 0 { - t.Fatalf("expected exit 0, got: %d", code) - } + code = cmd.Run([]string{"-address=" + url, allocID[:13]}) + must.Zero(t, code) + out = ui.OutputWriter.String() - if !strings.Contains(out, "Created") { - t.Fatalf("expected to have 'Created' but saw: %s", out) - } + must.StrContains(t, out, "Created") ui.OutputWriter.Reset() - if code := cmd.Run([]string{"-address=" + url, "-verbose", allocId1}); code != 0 { - t.Fatalf("expected exit 0, got: %d", code) - } - out = ui.OutputWriter.String() - if !strings.Contains(out, allocId1) { - t.Fatal("expected to find alloc id in output") - } - ui.OutputWriter.Reset() + code = cmd.Run([]string{"-address=" + url, "-verbose", allocID}) + must.Zero(t, code) + out = ui.OutputWriter.String() + must.StrContains(t, out, allocID) } func TestAllocStatusCommand_RescheduleInfo(t *testing.T) { @@ -240,14 +220,14 @@ func TestAllocStatusCommand_RescheduleInfo(t *testing.T) { }, }, } - require.NoError(t, state.UpsertAllocs(structs.MsgTypeTestSetup, 1000, []*structs.Allocation{a})) + must.NoError(t, state.UpsertAllocs(structs.MsgTypeTestSetup, 1000, []*structs.Allocation{a})) if code := cmd.Run([]string{"-address=" + url, a.ID}); code != 0 { t.Fatalf("expected exit 0, got: %d", code) } out := ui.OutputWriter.String() - require.Contains(t, out, "Replacement Alloc ID") - require.Regexp(t, regexp.MustCompile(".*Reschedule Attempts\\s*=\\s*1/2"), out) + must.StrContains(t, out, "Replacement Alloc ID") + must.RegexMatch(t, regexp.MustCompile(".*Reschedule Attempts\\s*=\\s*1/2"), out) } func TestAllocStatusCommand_ScoreMetrics(t *testing.T) { @@ -283,19 +263,19 @@ func TestAllocStatusCommand_ScoreMetrics(t *testing.T) { }, }, } - require.NoError(t, state.UpsertAllocs(structs.MsgTypeTestSetup, 1000, []*structs.Allocation{a})) + must.NoError(t, state.UpsertAllocs(structs.MsgTypeTestSetup, 1000, []*structs.Allocation{a})) + + code := cmd.Run([]string{"-address=" + url, "-verbose", a.ID}) + must.Zero(t, code) - if code := cmd.Run([]string{"-address=" + url, "-verbose", a.ID}); code != 0 { - t.Fatalf("expected exit 0, got: %d", code) - } out := ui.OutputWriter.String() - require.Contains(t, out, "Placement Metrics") - require.Contains(t, out, mockNode1.ID) - require.Contains(t, out, mockNode2.ID) + must.StrContains(t, out, "Placement Metrics") + must.StrContains(t, out, mockNode1.ID) + must.StrContains(t, out, mockNode2.ID) // assert we sort headers alphabetically - require.Contains(t, out, "binpack node-affinity") - require.Contains(t, out, "final score") + must.StrContains(t, out, "binpack node-affinity") + must.StrContains(t, out, "final score") } func TestAllocStatusCommand_AutocompleteArgs(t *testing.T) { @@ -372,18 +352,18 @@ func TestAllocStatusCommand_HostVolumes(t *testing.T) { }, } summary := mock.JobSummary(alloc.JobID) - require.NoError(t, state.UpsertJobSummary(1004, summary)) - require.NoError(t, state.UpsertAllocs(structs.MsgTypeTestSetup, 1005, []*structs.Allocation{alloc})) + must.NoError(t, state.UpsertJobSummary(1004, summary)) + must.NoError(t, state.UpsertAllocs(structs.MsgTypeTestSetup, 1005, []*structs.Allocation{alloc})) ui := cli.NewMockUi() cmd := &AllocStatusCommand{Meta: Meta{Ui: ui}} - if code := cmd.Run([]string{"-address=" + url, "-verbose", alloc.ID}); code != 0 { - t.Fatalf("expected exit 0, got: %d", code) - } + code := cmd.Run([]string{"-address=" + url, "-verbose", alloc.ID}) + must.Zero(t, code) + out := ui.OutputWriter.String() - require.Contains(t, out, "Host Volumes") - require.Contains(t, out, fmt.Sprintf("%s true", vol0)) - require.NotContains(t, out, "CSI Volumes") + must.StrContains(t, out, "Host Volumes") + must.StrContains(t, out, fmt.Sprintf("%s true", vol0)) + must.StrNotContains(t, out, "CSI Volumes") } func TestAllocStatusCommand_CSIVolumes(t *testing.T) { @@ -404,7 +384,7 @@ func TestAllocStatusCommand_CSIVolumes(t *testing.T) { }, } err := state.UpsertNode(structs.MsgTypeTestSetup, 1001, node) - require.NoError(t, err) + must.NoError(t, err) vols := []*structs.CSIVolume{{ ID: vol0, @@ -417,7 +397,7 @@ func TestAllocStatusCommand_CSIVolumes(t *testing.T) { }}, }} err = state.UpsertCSIVolume(1002, vols) - require.NoError(t, err) + must.NoError(t, err) // Upsert the job and alloc alloc := mock.Alloc() @@ -448,8 +428,8 @@ func TestAllocStatusCommand_CSIVolumes(t *testing.T) { }, } summary := mock.JobSummary(alloc.JobID) - require.NoError(t, state.UpsertJobSummary(1004, summary)) - require.NoError(t, state.UpsertAllocs(structs.MsgTypeTestSetup, 1005, []*structs.Allocation{alloc})) + must.NoError(t, state.UpsertJobSummary(1004, summary)) + must.NoError(t, state.UpsertAllocs(structs.MsgTypeTestSetup, 1005, []*structs.Allocation{alloc})) ui := cli.NewMockUi() cmd := &AllocStatusCommand{Meta: Meta{Ui: ui}} @@ -457,7 +437,7 @@ func TestAllocStatusCommand_CSIVolumes(t *testing.T) { t.Fatalf("expected exit 0, got: %d", code) } out := ui.OutputWriter.String() - require.Contains(t, out, "CSI Volumes") - require.Contains(t, out, fmt.Sprintf("%s minnie", vol0)) - require.NotContains(t, out, "Host Volumes") + must.StrContains(t, out, "CSI Volumes") + must.StrContains(t, out, fmt.Sprintf("%s minnie", vol0)) + must.StrNotContains(t, out, "Host Volumes") } diff --git a/command/alloc_stop_test.go b/command/alloc_stop_test.go index 54b0f7c1e..cb20fce3d 100644 --- a/command/alloc_stop_test.go +++ b/command/alloc_stop_test.go @@ -1,15 +1,11 @@ package command import ( - "fmt" "testing" - "github.com/hashicorp/nomad/api" "github.com/hashicorp/nomad/ci" - "github.com/hashicorp/nomad/nomad/structs" - "github.com/hashicorp/nomad/testutil" "github.com/mitchellh/cli" - "github.com/stretchr/testify/require" + "github.com/shoenig/test/must" ) func TestAllocStopCommand_Implements(t *testing.T) { @@ -19,62 +15,61 @@ func TestAllocStopCommand_Implements(t *testing.T) { func TestAllocStop_Fails(t *testing.T) { srv, _, url := testServer(t, false, nil) - defer srv.Shutdown() + defer stopTestAgent(srv) - require := require.New(t) ui := cli.NewMockUi() cmd := &AllocStopCommand{Meta: Meta{Ui: ui}} // Fails on misuse - require.Equal(cmd.Run([]string{"some", "garbage", "args"}), 1, "Expected failure") - require.Contains(ui.ErrorWriter.String(), commandErrorText(cmd), "Expected help output") + code := cmd.Run([]string{"some", "garbage", "args"}) + must.One(t, code) + + out := ui.ErrorWriter.String() + must.StrContains(t, out, commandErrorText(cmd)) + ui.ErrorWriter.Reset() // Fails on connection failure - require.Equal(cmd.Run([]string{"-address=nope", "foobar"}), 1, "expected failure") - require.Contains(ui.ErrorWriter.String(), "Error querying allocation") + code = cmd.Run([]string{"-address=nope", "foobar"}) + must.One(t, code) + + out = ui.ErrorWriter.String() + must.StrContains(t, out, "Error querying allocation") + ui.ErrorWriter.Reset() // Fails on missing alloc - require.Equal(cmd.Run([]string{"-address=" + url, "26470238-5CF2-438F-8772-DC67CFB0705C"}), 1) - require.Contains(ui.ErrorWriter.String(), "No allocation(s) with prefix or id") + code = cmd.Run([]string{"-address=" + url, "26470238-5CF2-438F-8772-DC67CFB0705C"}) + must.One(t, code) + + out = ui.ErrorWriter.String() + must.StrContains(t, out, "No allocation(s) with prefix or id") ui.ErrorWriter.Reset() // Fail on identifier with too few characters - require.Equal(cmd.Run([]string{"-address=" + url, "2"}), 1) - require.Contains(ui.ErrorWriter.String(), "must contain at least two characters") + code = cmd.Run([]string{"-address=" + url, "2"}) + must.One(t, code) + + out = ui.ErrorWriter.String() + must.StrContains(t, out, "must contain at least two characters") ui.ErrorWriter.Reset() // Identifiers with uneven length should produce a query result - require.Equal(cmd.Run([]string{"-address=" + url, "123"}), 1) - require.Contains(ui.ErrorWriter.String(), "No allocation(s) with prefix or id") - ui.ErrorWriter.Reset() + code = cmd.Run([]string{"-address=" + url, "123"}) + must.One(t, code) + + out = ui.ErrorWriter.String() + must.StrContains(t, out, "No allocation(s) with prefix or id") } func TestAllocStop_Run(t *testing.T) { ci.Parallel(t) srv, client, url := testServer(t, true, nil) - defer srv.Shutdown() - - require := require.New(t) + defer stopTestAgent(srv) // Wait for a node to be ready - testutil.WaitForResult(func() (bool, error) { - nodes, _, err := client.Nodes().List(nil) - if err != nil { - return false, err - } - for _, node := range nodes { - if _, ok := node.Drivers["mock_driver"]; ok && - node.Status == structs.NodeStatusReady { - return true, nil - } - } - return false, fmt.Errorf("no ready nodes") - }, func(err error) { - t.Fatalf("err: %v", err) - }) + waitForNodes(t, client) ui := cli.NewMockUi() cmd := &AllocStopCommand{Meta: Meta{Ui: ui}} @@ -82,34 +77,23 @@ func TestAllocStop_Run(t *testing.T) { jobID := "job1_sfx" job1 := testJob(jobID) resp, _, err := client.Jobs().Register(job1, nil) - require.NoError(err) - if code := waitForSuccess(ui, client, fullId, t, resp.EvalID); code != 0 { - t.Fatalf("status code non zero saw %d", code) - } + must.NoError(t, err) + + code := waitForSuccess(ui, client, fullId, t, resp.EvalID) + must.Zero(t, code) + // get an alloc id - allocId1 := "" + allocID := "" if allocs, _, err := client.Jobs().Allocations(jobID, false, nil); err == nil { if len(allocs) > 0 { - allocId1 = allocs[0].ID + allocID = allocs[0].ID } } - require.NotEmpty(allocId1, "unable to find allocation") + must.NotEq(t, "", allocID) // Wait for alloc to be running - testutil.WaitForResult(func() (bool, error) { - alloc, _, err := client.Allocations().Info(allocId1, nil) - if err != nil { - return false, err - } - if alloc.ClientStatus == api.AllocClientStatusRunning { - return true, nil - } - return false, fmt.Errorf("alloc is not running, is: %s", alloc.ClientStatus) - }, func(err error) { - t.Fatalf("err: %v", err) - }) + waitForAllocRunning(t, client, allocID) - require.Equal(cmd.Run([]string{"-address=" + url, allocId1}), 0, "expected successful exit code") - - ui.OutputWriter.Reset() + code = cmd.Run([]string{"-address=" + url, allocID}) + must.Zero(t, code) } diff --git a/command/check_test.go b/command/check_test.go index ea6af4f8d..219458598 100644 --- a/command/check_test.go +++ b/command/check_test.go @@ -6,25 +6,22 @@ import ( "github.com/hashicorp/nomad/ci" "github.com/mitchellh/cli" + "github.com/shoenig/test/must" ) func TestAgentCheckCommand_ServerHealth(t *testing.T) { ci.Parallel(t) srv, _, url := testServer(t, false, nil) - defer srv.Shutdown() + defer stopTestAgent(srv) ui := cli.NewMockUi() cmd := &AgentCheckCommand{Meta: Meta{Ui: ui}} address := fmt.Sprintf("-address=%s", url) code := cmd.Run([]string{address}) - if code != HealthPass { - t.Fatalf("expected exit: %v, actual: %d", HealthPass, code) - } + must.Eq(t, HealthPass, code) minPeers := fmt.Sprintf("-min-peers=%v", 3) code = cmd.Run([]string{address, minPeers}) - if code != HealthCritical { - t.Fatalf("expected exitcode: %v, actual: %v", HealthCritical, code) - } + must.Eq(t, HealthCritical, code) } diff --git a/command/config_validate_test.go b/command/config_validate_test.go index 111b15806..78ec2197f 100644 --- a/command/config_validate_test.go +++ b/command/config_validate_test.go @@ -1,12 +1,13 @@ package command import ( - "io/ioutil" + "os" "path/filepath" "testing" "github.com/hashicorp/nomad/ci" "github.com/mitchellh/cli" + "github.com/shoenig/test/must" ) func TestConfigValidateCommand_FailWithEmptyDir(t *testing.T) { @@ -18,9 +19,7 @@ func TestConfigValidateCommand_FailWithEmptyDir(t *testing.T) { args := []string{fh} code := cmd.Run(args) - if code != 1 { - t.Fatalf("expected exit 1, actual: %d", code) - } + must.One(t, code) } func TestConfigValidateCommand_SucceedWithMinimalConfigFile(t *testing.T) { @@ -28,22 +27,18 @@ func TestConfigValidateCommand_SucceedWithMinimalConfigFile(t *testing.T) { fh := t.TempDir() fp := filepath.Join(fh, "config.hcl") - err := ioutil.WriteFile(fp, []byte(`data_dir="/" + err := os.WriteFile(fp, []byte(`data_dir="/" client { enabled = true }`), 0644) - if err != nil { - t.Fatalf("err: %s", err) - } + must.NoError(t, err) ui := cli.NewMockUi() cmd := &ConfigValidateCommand{Meta: Meta{Ui: ui}} args := []string{fh} code := cmd.Run(args) - if code != 0 { - t.Fatalf("expected exit 0, actual: %d", code) - } + must.Zero(t, code) } func TestConfigValidateCommand_FailOnParseBadConfigFile(t *testing.T) { @@ -51,19 +46,15 @@ func TestConfigValidateCommand_FailOnParseBadConfigFile(t *testing.T) { fh := t.TempDir() fp := filepath.Join(fh, "config.hcl") - err := ioutil.WriteFile(fp, []byte(`a: b`), 0644) - if err != nil { - t.Fatalf("err: %s", err) - } + err := os.WriteFile(fp, []byte(`a: b`), 0644) + must.NoError(t, err) ui := cli.NewMockUi() cmd := &ConfigValidateCommand{Meta: Meta{Ui: ui}} args := []string{fh} code := cmd.Run(args) - if code != 1 { - t.Fatalf("expected exit 1, actual: %d", code) - } + must.One(t, code) } func TestConfigValidateCommand_FailOnValidateParsableConfigFile(t *testing.T) { @@ -71,20 +62,16 @@ func TestConfigValidateCommand_FailOnValidateParsableConfigFile(t *testing.T) { fh := t.TempDir() fp := filepath.Join(fh, "config.hcl") - err := ioutil.WriteFile(fp, []byte(`data_dir="../" + err := os.WriteFile(fp, []byte(`data_dir="../" client { - enabled = true + enabled = true }`), 0644) - if err != nil { - t.Fatalf("err: %s", err) - } + must.NoError(t, err) ui := cli.NewMockUi() cmd := &ConfigValidateCommand{Meta: Meta{Ui: ui}} args := []string{fh} code := cmd.Run(args) - if code != 1 { - t.Fatalf("expected exit 1, actual: %d", code) - } + must.One(t, code) } diff --git a/command/testing_test.go b/command/testing_test.go index 59283c46f..d38a3bde0 100644 --- a/command/testing_test.go +++ b/command/testing_test.go @@ -129,6 +129,21 @@ func waitForNodes(t *testing.T, client *api.Client) { }) } +func waitForAllocRunning(t *testing.T, client *api.Client, allocID string) { + testutil.WaitForResult(func() (bool, error) { + alloc, _, err := client.Allocations().Info(allocID, nil) + if err != nil { + return false, err + } + if alloc.ClientStatus == api.AllocClientStatusRunning { + return true, nil + } + return false, fmt.Errorf("alloc status: %s", alloc.ClientStatus) + }, func(err error) { + t.Fatalf("timed out waiting for alloc to be running: %v", err) + }) +} + func stopTestAgent(a *agent.TestAgent) { _ = a.Shutdown() }