diff --git a/scheduler/feasible_test.go b/scheduler/feasible_test.go index fcaf6bbd0..2f5416a3d 100644 --- a/scheduler/feasible_test.go +++ b/scheduler/feasible_test.go @@ -19,15 +19,7 @@ func TestRandomIterator(t *testing.T) { copy(nc, nodes) rand := NewRandomIterator(ctx, nc) - var out []*structs.Node - for { - next := rand.Next() - if next == nil { - break - } - out = append(out, next) - } - + out := collectFeasible(rand) if len(out) != len(nodes) { t.Fatalf("missing nodes") } @@ -54,15 +46,7 @@ func TestDriverIterator(t *testing.T) { } driver := NewDriverIterator(ctx, static, drivers) - var out []*structs.Node - for { - next := driver.Next() - if next == nil { - break - } - out = append(out, next) - } - + out := collectFeasible(driver) if len(out) != 2 { t.Fatalf("missing nodes") } @@ -99,15 +83,7 @@ func TestConstraintIterator(t *testing.T) { } constr := NewConstraintIterator(ctx, static, constraints) - var out []*structs.Node - for { - next := constr.Next() - if next == nil { - break - } - out = append(out, next) - } - + out := collectFeasible(constr) if len(out) != 1 { t.Fatalf("missing nodes") } @@ -228,3 +204,14 @@ func TestCheckConstraint(t *testing.T) { } } } + +func collectFeasible(iter FeasibleIterator) (out []*structs.Node) { + for { + next := iter.Next() + if next == nil { + break + } + out = append(out, next) + } + return +} diff --git a/scheduler/rank.go b/scheduler/rank.go index a907a12e5..9ce93c439 100644 --- a/scheduler/rank.go +++ b/scheduler/rank.go @@ -128,14 +128,17 @@ func (iter *BinPackIterator) Next() *RankedNode { // Add the resources we are trying to fit proposed = append(proposed, &structs.Allocation{Resources: iter.resources}) - // Check if these allocations fit, use a negative score - // to indicate an impossible choice + // Check if these allocations fit, if they do not, simply skip this node fit, util, _ := structs.AllocsFit(option.Node, proposed) if !fit { - option.Score = -1 - return option + continue } + // XXX: For now we completely ignore evictions. We should use that flag + // to determine if its possible to evict other lower priority allocations + // to make room. This explodes the search space, so it must be done + // carefully. + // Score the fit normally otherwise option.Score = structs.ScoreFit(option.Node, util) return option diff --git a/scheduler/rank_test.go b/scheduler/rank_test.go index 301eaeb7d..32e41ede3 100644 --- a/scheduler/rank_test.go +++ b/scheduler/rank_test.go @@ -17,19 +17,44 @@ func TestFeasibleRankIterator(t *testing.T) { feasible := NewFeasibleRankIterator(ctx, static) - var out []*RankedNode - for { - next := feasible.Next() - if next == nil { - break - } - out = append(out, next) - } - + out := collectRanked(feasible) if len(out) != len(nodes) { t.Fatalf("bad: %v", out) } } func TestBinPackIterator(t *testing.T) { + _, ctx := testContext(t) + nodes := []*RankedNode{ + &RankedNode{ + Node: mock.Node(), + }, + &RankedNode{ + Node: mock.Node(), + }, + &RankedNode{ + Node: mock.Node(), + }, + } + static := NewStaticRankIterator(ctx, nodes) + + alloc := mock.Alloc() + resources := alloc.Resources + binp := NewBinPackIterator(ctx, static, resources, false, 0) + + out := collectRanked(binp) + if len(out) != 3 { + t.Fatalf("Bad: %v", out) + } +} + +func collectRanked(iter RankIterator) (out []*RankedNode) { + for { + next := iter.Next() + if next == nil { + break + } + out = append(out, next) + } + return } diff --git a/scheduler/select_test.go b/scheduler/select_test.go index d04eb805a..d7b7401ef 100644 --- a/scheduler/select_test.go +++ b/scheduler/select_test.go @@ -26,15 +26,7 @@ func TestLimitIterator(t *testing.T) { limit := NewLimitIterator(ctx, static, 2) - var out []*RankedNode - for { - next := limit.Next() - if next == nil { - break - } - out = append(out, next) - } - + out := collectRanked(limit) if len(out) != 2 { t.Fatalf("bad: %v", out) } @@ -63,15 +55,7 @@ func TestMaxScoreIterator(t *testing.T) { max := NewMaxScoreIterator(ctx, static) - var out []*RankedNode - for { - next := max.Next() - if next == nil { - break - } - out = append(out, next) - } - + out := collectRanked(max) if len(out) != 1 { t.Fatalf("bad: %v", out) }