mirror of
https://github.com/kemko/nomad.git
synced 2026-01-06 10:25:42 +03:00
Use heap to store top K scoring nodes.
Scoring metadata is now aggregated by scorer type to make it easier to parse when reading it in the CLI.
This commit is contained in:
@@ -224,6 +224,60 @@ func TestAllocStatusCommand_RescheduleInfo(t *testing.T) {
|
||||
require.Regexp(regexp.MustCompile(".*Reschedule Attempts\\s*=\\s*1/2"), out)
|
||||
}
|
||||
|
||||
func TestAllocStatusCommand_ScoreMetrics(t *testing.T) {
|
||||
t.Parallel()
|
||||
srv, client, url := testServer(t, true, nil)
|
||||
defer srv.Shutdown()
|
||||
|
||||
// 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 node.Status == structs.NodeStatusReady {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
return false, fmt.Errorf("no ready nodes")
|
||||
}, func(err error) {
|
||||
t.Fatalf("err: %v", err)
|
||||
})
|
||||
|
||||
ui := new(cli.MockUi)
|
||||
cmd := &AllocStatusCommand{Meta: Meta{Ui: ui}}
|
||||
// Test reschedule attempt info
|
||||
require := require.New(t)
|
||||
state := srv.Agent.Server().State()
|
||||
a := mock.Alloc()
|
||||
mockNode1 := mock.Node()
|
||||
mockNode2 := mock.Node()
|
||||
a.Metrics = &structs.AllocMetric{
|
||||
ScoreMetaData: map[string][]*structs.NodeScoreMeta{
|
||||
"binpack": []*structs.NodeScoreMeta{
|
||||
{NodeID: mockNode1.ID, Score: 0.77},
|
||||
{NodeID: mockNode2.ID, Score: 0.75},
|
||||
},
|
||||
"node-affinity": []*structs.NodeScoreMeta{
|
||||
{NodeID: mockNode1.ID, Score: 0.5},
|
||||
{NodeID: mockNode2.ID, Score: 0.33},
|
||||
},
|
||||
},
|
||||
}
|
||||
require.Nil(state.UpsertAllocs(1000, []*structs.Allocation{a}))
|
||||
|
||||
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(out, "Placement Metrics")
|
||||
require.Contains(out, fmt.Sprintf("Scorer %q, Node %q", "binpack", mockNode1.ID))
|
||||
require.Contains(out, fmt.Sprintf("Scorer %q, Node %q", "binpack", mockNode2.ID))
|
||||
require.Contains(out, fmt.Sprintf("Scorer %q, Node %q", "node-affinity", mockNode1.ID))
|
||||
require.Contains(out, fmt.Sprintf("Scorer %q, Node %q", "binpack", mockNode2.ID))
|
||||
}
|
||||
|
||||
func TestAllocStatusCommand_AutocompleteArgs(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
t.Parallel()
|
||||
|
||||
@@ -373,8 +373,17 @@ func formatAllocMetrics(metrics *api.AllocationMetric, scores bool, prefix strin
|
||||
|
||||
// Print scores
|
||||
if scores {
|
||||
for name, score := range metrics.Scores {
|
||||
out += fmt.Sprintf("%s* Score %q = %f\n", prefix, name, score)
|
||||
if len(metrics.ScoreMetaData) > 0 {
|
||||
for scorer, scoreMeta := range metrics.ScoreMetaData {
|
||||
for _, nodeScore := range scoreMeta {
|
||||
out += fmt.Sprintf("%s* Scorer %q, Node %q = %f\n", prefix, scorer, nodeScore.NodeID, nodeScore.Score)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Backwards compatibility for old allocs
|
||||
for name, score := range metrics.Scores {
|
||||
out += fmt.Sprintf("%s* Score %q = %f\n", prefix, name, score)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user