cli: updated recommendation commands and test to remove duplication of autocompletion code

This commit is contained in:
Chris Baker 2020-11-11 11:39:26 +00:00
parent e3c0ea654d
commit 2deb77dcf5
6 changed files with 46 additions and 134 deletions

View File

@ -5,7 +5,6 @@ import (
"strings"
"github.com/hashicorp/nomad/api"
"github.com/hashicorp/nomad/api/contexts"
"github.com/mitchellh/cli"
"github.com/posener/complete"
@ -17,6 +16,7 @@ var _ cli.Command = &RecommendationApplyCommand{}
// RecommendationApplyCommand implements cli.Command.
type RecommendationApplyCommand struct {
Meta
RecommendationAutocompleteCommand
}
// Help satisfies the cli.Command Help function.
@ -62,21 +62,6 @@ func (r *RecommendationApplyCommand) AutocompleteFlags() complete.Flags {
})
}
func (r *RecommendationApplyCommand) AutocompleteArgs() complete.Predictor {
return complete.PredictFunc(func(a complete.Args) []string {
client, err := r.Meta.Client()
if err != nil {
return nil
}
resp, _, err := client.Search().PrefixSearch(a.Last, contexts.Recommendations, nil)
if err != nil {
return []string{}
}
return resp.Matches[contexts.Recommendations]
})
}
// Name returns the name of this command.
func (r *RecommendationApplyCommand) Name() string { return "recommendation apply" }

View File

@ -4,12 +4,11 @@ import (
"fmt"
"testing"
"github.com/mitchellh/cli"
"github.com/stretchr/testify/require"
"github.com/hashicorp/nomad/api"
"github.com/hashicorp/nomad/testutil"
"github.com/mitchellh/cli"
"github.com/posener/complete"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestRecommendationApplyCommand_Run(t *testing.T) {
@ -87,44 +86,10 @@ func TestRecommendationApplyCommand_Run(t *testing.T) {
}
func TestRecommendationApplyCommand_AutocompleteArgs(t *testing.T) {
assert := assert.New(t)
t.Parallel()
srv, client, url := testServer(t, true, nil)
defer srv.Shutdown()
// Register a test job to write a recommendation against.
ui := cli.NewMockUi()
testJob := testJob("recommendation_list")
regResp, _, err := client.Jobs().Register(testJob, nil)
require.NoError(t, err)
registerCode := waitForSuccess(ui, client, fullId, t, regResp.EvalID)
require.Equal(t, 0, registerCode)
// Write a recommendation.
rec := &api.Recommendation{
JobID: *testJob.ID,
Group: *testJob.TaskGroups[0].Name,
Task: testJob.TaskGroups[0].Tasks[0].Name,
Resource: "CPU",
Value: 1050,
Meta: map[string]interface{}{"test-meta-entry": "test-meta-value"},
Stats: map[string]float64{"p13": 1.13},
}
rec, _, err = client.Recommendations().Upsert(rec, nil)
if srv.Enterprise {
require.NoError(t, err)
} else {
require.Error(t, err, "Nomad Enterprise only endpoint")
return
}
cmd := &RecommendationApplyCommand{Meta: Meta{Ui: ui, flagAddress: url}}
prefix := rec.ID[:5]
args := complete.Args{Last: prefix}
predictor := cmd.AutocompleteArgs()
res := predictor.Predict(args)
assert.Equal(1, len(res))
assert.Equal(rec.ID, res[0])
cmd := RecommendationApplyCommand{Meta: Meta{Ui: ui, flagAddress: url}}
testRecommendationAutocompleteCommand(t, client, srv, ui, &cmd.RecommendationAutocompleteCommand)
}

View File

@ -13,9 +13,31 @@ import (
// Ensure RecommendationDismissCommand satisfies the cli.Command interface.
var _ cli.Command = &RecommendationDismissCommand{}
// RecommendationAutocompleteCommand provides AutocompleteArgs for all
// recommendation commands that support prefix-search autocompletion
type RecommendationAutocompleteCommand struct {
Meta
}
func (r *RecommendationAutocompleteCommand) AutocompleteArgs() complete.Predictor {
return complete.PredictFunc(func(a complete.Args) []string {
client, err := r.Meta.Client()
if err != nil {
return nil
}
resp, _, err := client.Search().PrefixSearch(a.Last, contexts.Recommendations, nil)
if err != nil {
return []string{}
}
return resp.Matches[contexts.Recommendations]
})
}
// RecommendationDismissCommand implements cli.Command.
type RecommendationDismissCommand struct {
Meta
RecommendationAutocompleteCommand
}
// Help satisfies the cli.Command Help function.
@ -41,21 +63,6 @@ func (r *RecommendationDismissCommand) AutocompleteFlags() complete.Flags {
complete.Flags{})
}
func (r *RecommendationDismissCommand) AutocompleteArgs() complete.Predictor {
return complete.PredictFunc(func(a complete.Args) []string {
client, err := r.Meta.Client()
if err != nil {
return nil
}
resp, _, err := client.Search().PrefixSearch(a.Last, contexts.Recommendations, nil)
if err != nil {
return []string{}
}
return resp.Matches[contexts.Recommendations]
})
}
// Name returns the name of this command.
func (r *RecommendationDismissCommand) Name() string { return "recommendation dismiss" }

View File

@ -5,6 +5,7 @@ import (
"testing"
"github.com/hashicorp/nomad/api"
"github.com/hashicorp/nomad/command/agent"
"github.com/hashicorp/nomad/testutil"
"github.com/mitchellh/cli"
"github.com/posener/complete"
@ -84,15 +85,21 @@ func TestRecommendationDismissCommand_Run(t *testing.T) {
}
func TestRecommendationDismissCommand_AutocompleteArgs(t *testing.T) {
assert := assert.New(t)
t.Parallel()
srv, client, url := testServer(t, true, nil)
defer srv.Shutdown()
// Register a test job to write a recommendation against.
ui := cli.NewMockUi()
testJob := testJob("recommendation_list")
cmd := &RecommendationDismissCommand{Meta: Meta{Ui: ui, flagAddress: url}}
testRecommendationAutocompleteCommand(t, client, srv, ui, &cmd.RecommendationAutocompleteCommand)
}
func testRecommendationAutocompleteCommand(t *testing.T, client *api.Client, srv *agent.TestAgent, ui *cli.MockUi, cmd *RecommendationAutocompleteCommand) {
assert := assert.New(t)
t.Parallel()
// Register a test job to write a recommendation against.
testJob := testJob("recommendation_autocomplete")
regResp, _, err := client.Jobs().Register(testJob, nil)
require.NoError(t, err)
registerCode := waitForSuccess(ui, client, fullId, t, regResp.EvalID)
@ -116,7 +123,6 @@ func TestRecommendationDismissCommand_AutocompleteArgs(t *testing.T) {
return
}
cmd := &RecommendationDismissCommand{Meta: Meta{Ui: ui, flagAddress: url}}
prefix := rec.ID[:5]
args := complete.Args{Last: prefix}
predictor := cmd.AutocompleteArgs()

View File

@ -7,8 +7,6 @@ import (
"github.com/mitchellh/cli"
"github.com/posener/complete"
"github.com/hashicorp/nomad/api/contexts"
)
// Ensure RecommendationInfoCommand satisfies the cli.Command interface.
@ -17,6 +15,7 @@ var _ cli.Command = &RecommendationInfoCommand{}
// RecommendationInfoCommand implements cli.Command.
type RecommendationInfoCommand struct {
Meta
RecommendationAutocompleteCommand
}
// Help satisfies the cli.Command Help function.
@ -54,21 +53,6 @@ func (r *RecommendationInfoCommand) AutocompleteFlags() complete.Flags {
})
}
func (r *RecommendationInfoCommand) AutocompleteArgs() complete.Predictor {
return complete.PredictFunc(func(a complete.Args) []string {
client, err := r.Meta.Client()
if err != nil {
return nil
}
resp, _, err := client.Search().PrefixSearch(a.Last, contexts.Recommendations, nil)
if err != nil {
return []string{}
}
return resp.Matches[contexts.Recommendations]
})
}
// Name returns the name of this command.
func (r *RecommendationInfoCommand) Name() string { return "recommendation info" }

View File

@ -4,12 +4,11 @@ import (
"fmt"
"testing"
"github.com/mitchellh/cli"
"github.com/stretchr/testify/require"
"github.com/hashicorp/nomad/api"
"github.com/hashicorp/nomad/testutil"
"github.com/mitchellh/cli"
"github.com/posener/complete"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestRecommendationInfoCommand_Run(t *testing.T) {
@ -85,44 +84,10 @@ func TestRecommendationInfoCommand_Run(t *testing.T) {
}
func TestRecommendationInfoCommand_AutocompleteArgs(t *testing.T) {
assert := assert.New(t)
t.Parallel()
srv, client, url := testServer(t, true, nil)
defer srv.Shutdown()
// Register a test job to write a recommendation against.
ui := cli.NewMockUi()
testJob := testJob("recommendation_list")
regResp, _, err := client.Jobs().Register(testJob, nil)
require.NoError(t, err)
registerCode := waitForSuccess(ui, client, fullId, t, regResp.EvalID)
require.Equal(t, 0, registerCode)
// Write a recommendation.
rec := &api.Recommendation{
JobID: *testJob.ID,
Group: *testJob.TaskGroups[0].Name,
Task: testJob.TaskGroups[0].Tasks[0].Name,
Resource: "CPU",
Value: 1050,
Meta: map[string]interface{}{"test-meta-entry": "test-meta-value"},
Stats: map[string]float64{"p13": 1.13},
}
rec, _, err = client.Recommendations().Upsert(rec, nil)
if srv.Enterprise {
require.NoError(t, err)
} else {
require.Error(t, err, "Nomad Enterprise only endpoint")
return
}
cmd := &RecommendationInfoCommand{Meta: Meta{Ui: ui, flagAddress: url}}
prefix := rec.ID[:5]
args := complete.Args{Last: prefix}
predictor := cmd.AutocompleteArgs()
res := predictor.Predict(args)
assert.Equal(1, len(res))
assert.Equal(rec.ID, res[0])
cmd := RecommendationInfoCommand{Meta: Meta{Ui: ui, flagAddress: url}}
testRecommendationAutocompleteCommand(t, client, srv, ui, &cmd.RecommendationAutocompleteCommand)
}