open-nomad/command/recommendation_list_test.go
Seth Hoenig fa0dc05b7a tests: wait on client in a couple of tests
These tend to fail on GHA, where I believe the client is not
starting up fast enough before making requests. So wait on
the client agent first.

```
=== RUN   TestDebug_CapturedFiles
    operator_debug_test.go:422: serverName: TestDebug_CapturedFiles.global, clientID, 1afb00e6-13f2-d8d6-d0f9-745a3fd6e8e4
    operator_debug_test.go:492:
        	Error Trace:	operator_debug_test.go:492
        	Error:      	Should be empty, but was No node(s) with prefix "1afb00e6-13f2-d8d6-d0f9-745a3fd6e8e4" found
        	            	Failed to retrieve clients, 0 nodes found in list: 1afb00e6-13f2-d8d6-d0f9-745a3fd6e8e4
        	Test:       	TestDebug_CapturedFiles
--- FAIL: TestDebug_CapturedFiles (0.08s)
```
2022-03-30 08:48:23 -05:00

167 lines
7.1 KiB
Go

package command
import (
"sort"
"testing"
"github.com/hashicorp/nomad/api"
"github.com/hashicorp/nomad/ci"
"github.com/hashicorp/nomad/testutil"
"github.com/mitchellh/cli"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestRecommendationListCommand_Run(t *testing.T) {
ci.Parallel(t)
require := require.New(t)
srv, client, url := testServer(t, true, nil)
defer srv.Shutdown()
testutil.WaitForLeader(t, srv.Agent.RPC)
clientID := srv.Agent.Client().NodeID()
testutil.WaitForClient(t, srv.Agent.Client().RPC, clientID, srv.Agent.Client().Region())
ui := cli.NewMockUi()
cmd := &RecommendationListCommand{Meta: Meta{Ui: ui}}
// Perform an initial list, which should return zero results.
code := cmd.Run([]string{"-address=" + url})
if srv.Enterprise {
require.Equal(0, code)
out := ui.OutputWriter.String()
require.Contains(out, "No recommendations found")
} else {
require.Equal(1, code)
require.Contains(ui.ErrorWriter.String(), "Nomad Enterprise only endpoint")
}
// Register a test job to write a recommendation against.
testJob := testJob("recommendation_list")
regResp, _, err := client.Jobs().Register(testJob, nil)
require.NoError(err)
registerCode := waitForSuccess(ui, client, fullId, t, regResp.EvalID)
require.Equal(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},
}
_, _, err = client.Recommendations().Upsert(&rec, nil)
if srv.Enterprise {
require.NoError(err)
} else {
require.Error(err, "Nomad Enterprise only endpoint")
}
// Perform a new list which should yield results.
code = cmd.Run([]string{"-address=" + url})
if srv.Enterprise {
require.Equal(0, code)
out := ui.OutputWriter.String()
require.Contains(out, "ID")
require.Contains(out, "Job")
require.Contains(out, "Group")
require.Contains(out, "Task")
require.Contains(out, "Resource")
require.Contains(out, "Value")
require.Contains(out, "CPU")
} else {
require.Equal(1, code)
require.Contains(ui.ErrorWriter.String(), "Nomad Enterprise only endpoint")
}
}
func TestRecommendationListCommand_Sort(t *testing.T) {
ci.Parallel(t)
testCases := []struct {
inputRecommendationList []*api.Recommendation
expectedOutputList []*api.Recommendation
name string
}{
{
inputRecommendationList: []*api.Recommendation{
{Namespace: "default", JobID: "example", Group: "cache", Task: "redis", Resource: "MemoryMB"},
{Namespace: "default", JobID: "example", Group: "cache", Task: "redis", Resource: "CPU"},
},
expectedOutputList: []*api.Recommendation{
{Namespace: "default", JobID: "example", Group: "cache", Task: "redis", Resource: "CPU"},
{Namespace: "default", JobID: "example", Group: "cache", Task: "redis", Resource: "MemoryMB"},
},
name: "single job with both resources",
},
{
inputRecommendationList: []*api.Recommendation{
{Namespace: "default", JobID: "example", Group: "cache", Task: "redis", Resource: "MemoryMB"},
{Namespace: "default", JobID: "example", Group: "cache", Task: "redis", Resource: "CPU"},
{Namespace: "default", JobID: "example", Group: "cache", Task: "mongodb", Resource: "MemoryMB"},
{Namespace: "default", JobID: "example", Group: "cache", Task: "mongodb", Resource: "CPU"},
},
expectedOutputList: []*api.Recommendation{
{Namespace: "default", JobID: "example", Group: "cache", Task: "mongodb", Resource: "CPU"},
{Namespace: "default", JobID: "example", Group: "cache", Task: "mongodb", Resource: "MemoryMB"},
{Namespace: "default", JobID: "example", Group: "cache", Task: "redis", Resource: "CPU"},
{Namespace: "default", JobID: "example", Group: "cache", Task: "redis", Resource: "MemoryMB"},
},
name: "single job with multiple groups",
},
{
inputRecommendationList: []*api.Recommendation{
{Namespace: "default", JobID: "example", Group: "cache", Task: "redis", Resource: "MemoryMB"},
{Namespace: "default", JobID: "example", Group: "cache", Task: "redis", Resource: "CPU"},
{Namespace: "default", JobID: "distro", Group: "cache", Task: "redis", Resource: "MemoryMB"},
{Namespace: "default", JobID: "example", Group: "cache", Task: "mongodb", Resource: "MemoryMB"},
{Namespace: "default", JobID: "example", Group: "cache", Task: "mongodb", Resource: "CPU"},
{Namespace: "default", JobID: "distro", Group: "cache", Task: "redis", Resource: "CPU"},
},
expectedOutputList: []*api.Recommendation{
{Namespace: "default", JobID: "distro", Group: "cache", Task: "redis", Resource: "CPU"},
{Namespace: "default", JobID: "distro", Group: "cache", Task: "redis", Resource: "MemoryMB"},
{Namespace: "default", JobID: "example", Group: "cache", Task: "mongodb", Resource: "CPU"},
{Namespace: "default", JobID: "example", Group: "cache", Task: "mongodb", Resource: "MemoryMB"},
{Namespace: "default", JobID: "example", Group: "cache", Task: "redis", Resource: "CPU"},
{Namespace: "default", JobID: "example", Group: "cache", Task: "redis", Resource: "MemoryMB"},
},
name: "multiple jobs",
},
{
inputRecommendationList: []*api.Recommendation{
{Namespace: "default", JobID: "example", Group: "cache", Task: "redis", Resource: "MemoryMB"},
{Namespace: "default", JobID: "example", Group: "cache", Task: "redis", Resource: "CPU"},
{Namespace: "cefault", JobID: "distro", Group: "cache", Task: "redis", Resource: "MemoryMB"},
{Namespace: "default", JobID: "distro", Group: "cache", Task: "redis", Resource: "MemoryMB"},
{Namespace: "default", JobID: "example", Group: "cache", Task: "mongodb", Resource: "MemoryMB"},
{Namespace: "default", JobID: "example", Group: "cache", Task: "mongodb", Resource: "CPU"},
{Namespace: "default", JobID: "distro", Group: "cache", Task: "redis", Resource: "CPU"},
{Namespace: "cefault", JobID: "distro", Group: "cache", Task: "redis", Resource: "CPU"},
},
expectedOutputList: []*api.Recommendation{
{Namespace: "cefault", JobID: "distro", Group: "cache", Task: "redis", Resource: "CPU"},
{Namespace: "cefault", JobID: "distro", Group: "cache", Task: "redis", Resource: "MemoryMB"},
{Namespace: "default", JobID: "distro", Group: "cache", Task: "redis", Resource: "CPU"},
{Namespace: "default", JobID: "distro", Group: "cache", Task: "redis", Resource: "MemoryMB"},
{Namespace: "default", JobID: "example", Group: "cache", Task: "mongodb", Resource: "CPU"},
{Namespace: "default", JobID: "example", Group: "cache", Task: "mongodb", Resource: "MemoryMB"},
{Namespace: "default", JobID: "example", Group: "cache", Task: "redis", Resource: "CPU"},
{Namespace: "default", JobID: "example", Group: "cache", Task: "redis", Resource: "MemoryMB"},
},
name: "multiple namespaces",
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
sortedRecs := recommendationList{r: tc.inputRecommendationList}
sort.Sort(sortedRecs)
assert.Equal(t, tc.expectedOutputList, sortedRecs.r, tc.name)
})
}
}