added some unit tests for -1 spread score

This commit is contained in:
Preetha Appan
2018-07-29 19:49:56 -05:00
parent f881c4f266
commit fc48be3656
2 changed files with 92 additions and 4 deletions

View File

@@ -5,9 +5,9 @@ import (
)
const (
// ImplicitTarget is used to represent any remaining attribute values
// implicitTarget is used to represent any remaining attribute values
// when target percentages don't add up to 100
ImplicitTarget = "*"
implicitTarget = "*"
)
// SpreadIterator is used to spread allocations across a specified attribute
@@ -139,7 +139,7 @@ func (iter *SpreadIterator) Next() *RankedNode {
desiredCount, ok := spreadDetails.desiredCounts[nValue]
if !ok {
// See if there is an implicit target
desiredCount, ok = spreadDetails.desiredCounts[ImplicitTarget]
desiredCount, ok = spreadDetails.desiredCounts[implicitTarget]
if !ok {
// The desired count for this attribute is zero if it gets here
// so use the maximum possible penalty for this node
@@ -241,7 +241,7 @@ func (iter *SpreadIterator) computeSpreadInfo(tg *structs.TaskGroup) {
// Account for remaining count only if there is any spread targets
if sumDesiredCounts > 0 && sumDesiredCounts < float64(totalCount) {
remainingCount := float64(totalCount) - sumDesiredCounts
si.desiredCounts[ImplicitTarget] = remainingCount
si.desiredCounts[implicitTarget] = remainingCount
}
spreadInfos[spread.Attribute] = si
iter.sumSpreadWeights += spread.Weight

View File

@@ -431,3 +431,91 @@ func TestSpreadIterator_EvenSpread(t *testing.T) {
}
}
// Test scenarios where the spread iterator sets maximum penalty (-1.0)
func TestSpreadIterator_MaxPenalty(t *testing.T) {
state, ctx := testContext(t)
var nodes []*RankedNode
// Add nodes in dc3 to the state store
for i := 0; i < 5; i++ {
node := mock.Node()
node.Datacenter = "dc3"
if err := state.UpsertNode(uint64(100+i), node); err != nil {
t.Fatalf("failed to upsert node: %v", err)
}
nodes = append(nodes, &RankedNode{Node: node})
}
static := NewStaticRankIterator(ctx, nodes)
job := mock.Job()
tg := job.TaskGroups[0]
job.TaskGroups[0].Count = 5
// Create spread target of 80% in dc1
// and 20% in dc2
spread := &structs.Spread{
Weight: 100,
Attribute: "${node.datacenter}",
SpreadTarget: []*structs.SpreadTarget{
{
Value: "dc1",
Percent: 80,
},
{
Value: "dc2",
Percent: 20,
},
},
}
tg.Spreads = []*structs.Spread{spread}
spreadIter := NewSpreadIterator(ctx, static)
spreadIter.SetJob(job)
spreadIter.SetTaskGroup(tg)
scoreNorm := NewScoreNormalizationIterator(ctx, spreadIter)
out := collectRanked(scoreNorm)
// All nodes are in dc3 so score should be -1
for _, rn := range out {
require.Equal(t, -1.0, rn.FinalScore)
}
// Reset scores
for _, node := range nodes {
node.Scores = nil
node.FinalScore = 0
}
// Create spread on attribute that doesn't exist on any nodes
spread = &structs.Spread{
Weight: 100,
Attribute: "${meta.foo}",
SpreadTarget: []*structs.SpreadTarget{
{
Value: "bar",
Percent: 80,
},
{
Value: "baz",
Percent: 20,
},
},
}
tg.Spreads = []*structs.Spread{spread}
static = NewStaticRankIterator(ctx, nodes)
spreadIter = NewSpreadIterator(ctx, static)
spreadIter.SetJob(job)
spreadIter.SetTaskGroup(tg)
scoreNorm = NewScoreNormalizationIterator(ctx, spreadIter)
out = collectRanked(scoreNorm)
// All nodes don't have the spread attribute so score should be -1
for _, rn := range out {
require.Equal(t, -1.0, rn.FinalScore)
}
}