2015-08-14 01:51:08 +00:00
|
|
|
package scheduler
|
|
|
|
|
|
|
|
import (
|
|
|
|
"reflect"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/hashicorp/nomad/nomad/mock"
|
2015-08-14 04:55:37 +00:00
|
|
|
"github.com/hashicorp/nomad/nomad/structs"
|
2015-08-14 01:51:08 +00:00
|
|
|
)
|
|
|
|
|
2015-09-07 18:30:13 +00:00
|
|
|
func TestServiceStack_SetNodes(t *testing.T) {
|
|
|
|
_, ctx := testContext(t)
|
|
|
|
stack := NewGenericStack(false, ctx, nil)
|
|
|
|
|
|
|
|
nodes := []*structs.Node{
|
|
|
|
mock.Node(),
|
2015-09-11 19:03:41 +00:00
|
|
|
mock.Node(),
|
|
|
|
mock.Node(),
|
|
|
|
mock.Node(),
|
|
|
|
mock.Node(),
|
|
|
|
mock.Node(),
|
|
|
|
mock.Node(),
|
|
|
|
mock.Node(),
|
2015-09-07 18:30:13 +00:00
|
|
|
}
|
|
|
|
stack.SetNodes(nodes)
|
|
|
|
|
2015-09-11 19:03:41 +00:00
|
|
|
// Check that our scan limit is updated
|
|
|
|
if stack.limit.limit != 3 {
|
|
|
|
t.Fatalf("bad limit %d", stack.limit.limit)
|
|
|
|
}
|
|
|
|
|
2015-09-07 18:30:13 +00:00
|
|
|
out := collectFeasible(stack.source)
|
|
|
|
if !reflect.DeepEqual(out, nodes) {
|
|
|
|
t.Fatalf("bad: %#v", out)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-08-14 01:51:08 +00:00
|
|
|
func TestServiceStack_SetJob(t *testing.T) {
|
|
|
|
_, ctx := testContext(t)
|
2015-08-14 05:35:48 +00:00
|
|
|
stack := NewGenericStack(false, ctx, nil)
|
2015-08-14 01:51:08 +00:00
|
|
|
|
|
|
|
job := mock.Job()
|
|
|
|
stack.SetJob(job)
|
|
|
|
|
|
|
|
if stack.binPack.priority != job.Priority {
|
|
|
|
t.Fatalf("bad")
|
|
|
|
}
|
|
|
|
if !reflect.DeepEqual(stack.jobConstraint.constraints, job.Constraints) {
|
|
|
|
t.Fatalf("bad")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestServiceStack_Select_Size(t *testing.T) {
|
2015-08-14 04:55:37 +00:00
|
|
|
_, ctx := testContext(t)
|
|
|
|
nodes := []*structs.Node{
|
|
|
|
mock.Node(),
|
|
|
|
}
|
2015-08-14 05:35:48 +00:00
|
|
|
stack := NewGenericStack(false, ctx, nodes)
|
2015-08-14 04:55:37 +00:00
|
|
|
|
|
|
|
job := mock.Job()
|
|
|
|
stack.SetJob(job)
|
|
|
|
node, size := stack.Select(job.TaskGroups[0])
|
|
|
|
if node == nil {
|
|
|
|
t.Fatalf("missing node %#v", ctx.Metrics())
|
|
|
|
}
|
|
|
|
if size == nil {
|
|
|
|
t.Fatalf("missing size")
|
|
|
|
}
|
|
|
|
|
|
|
|
if size.CPU != 0.5 || size.MemoryMB != 256 {
|
|
|
|
t.Fatalf("bad: %#v", size)
|
|
|
|
}
|
2015-08-14 04:58:55 +00:00
|
|
|
|
|
|
|
met := ctx.Metrics()
|
|
|
|
if met.AllocationTime == 0 {
|
|
|
|
t.Fatalf("missing time")
|
|
|
|
}
|
2015-08-14 01:51:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestServiceStack_Select_MetricsReset(t *testing.T) {
|
2015-08-14 04:55:37 +00:00
|
|
|
_, ctx := testContext(t)
|
|
|
|
nodes := []*structs.Node{
|
|
|
|
mock.Node(),
|
|
|
|
mock.Node(),
|
|
|
|
mock.Node(),
|
|
|
|
mock.Node(),
|
|
|
|
}
|
2015-08-14 05:35:48 +00:00
|
|
|
stack := NewGenericStack(false, ctx, nodes)
|
2015-08-14 04:55:37 +00:00
|
|
|
|
|
|
|
job := mock.Job()
|
|
|
|
stack.SetJob(job)
|
|
|
|
n1, _ := stack.Select(job.TaskGroups[0])
|
|
|
|
m1 := ctx.Metrics()
|
|
|
|
if n1 == nil {
|
|
|
|
t.Fatalf("missing node %#v", m1)
|
|
|
|
}
|
|
|
|
|
|
|
|
if m1.NodesEvaluated != 2 {
|
|
|
|
t.Fatalf("should only be 2")
|
|
|
|
}
|
|
|
|
|
|
|
|
n2, _ := stack.Select(job.TaskGroups[0])
|
|
|
|
m2 := ctx.Metrics()
|
|
|
|
if n2 == nil {
|
|
|
|
t.Fatalf("missing node %#v", m2)
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we don't reset, this would be 4
|
|
|
|
if m2.NodesEvaluated != 2 {
|
|
|
|
t.Fatalf("should only be 2")
|
|
|
|
}
|
2015-08-14 01:51:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestServiceStack_Select_DriverFilter(t *testing.T) {
|
2015-08-14 04:55:37 +00:00
|
|
|
_, ctx := testContext(t)
|
|
|
|
nodes := []*structs.Node{
|
|
|
|
mock.Node(),
|
|
|
|
mock.Node(),
|
|
|
|
}
|
|
|
|
zero := nodes[0]
|
|
|
|
zero.Attributes["driver.foo"] = "1"
|
|
|
|
|
2015-08-14 05:35:48 +00:00
|
|
|
stack := NewGenericStack(false, ctx, nodes)
|
2015-08-14 04:55:37 +00:00
|
|
|
|
|
|
|
job := mock.Job()
|
|
|
|
job.TaskGroups[0].Tasks[0].Driver = "foo"
|
|
|
|
stack.SetJob(job)
|
|
|
|
|
|
|
|
node, _ := stack.Select(job.TaskGroups[0])
|
|
|
|
if node == nil {
|
|
|
|
t.Fatalf("missing node %#v", ctx.Metrics())
|
|
|
|
}
|
|
|
|
|
|
|
|
if node.Node != zero {
|
|
|
|
t.Fatalf("bad")
|
|
|
|
}
|
2015-08-14 01:51:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestServiceStack_Select_ConstraintFilter(t *testing.T) {
|
2015-08-14 04:55:37 +00:00
|
|
|
_, ctx := testContext(t)
|
|
|
|
nodes := []*structs.Node{
|
|
|
|
mock.Node(),
|
|
|
|
mock.Node(),
|
|
|
|
}
|
|
|
|
zero := nodes[0]
|
2015-08-28 08:30:47 +00:00
|
|
|
zero.Attributes["kernel.name"] = "freebsd"
|
2015-08-14 04:55:37 +00:00
|
|
|
|
2015-08-14 05:35:48 +00:00
|
|
|
stack := NewGenericStack(false, ctx, nodes)
|
2015-08-14 04:55:37 +00:00
|
|
|
|
|
|
|
job := mock.Job()
|
|
|
|
job.Constraints[0].RTarget = "freebsd"
|
|
|
|
stack.SetJob(job)
|
|
|
|
|
|
|
|
node, _ := stack.Select(job.TaskGroups[0])
|
|
|
|
if node == nil {
|
|
|
|
t.Fatalf("missing node %#v", ctx.Metrics())
|
|
|
|
}
|
|
|
|
|
|
|
|
if node.Node != zero {
|
|
|
|
t.Fatalf("bad")
|
|
|
|
}
|
|
|
|
|
|
|
|
met := ctx.Metrics()
|
2015-08-14 04:58:55 +00:00
|
|
|
if met.NodesFiltered != 1 {
|
|
|
|
t.Fatalf("bad: %#v", met)
|
|
|
|
}
|
|
|
|
if met.ClassFiltered["linux-medium-pci"] != 1 {
|
|
|
|
t.Fatalf("bad: %#v", met)
|
|
|
|
}
|
2015-08-28 08:30:47 +00:00
|
|
|
if met.ConstraintFiltered["$attr.kernel.name = freebsd"] != 1 {
|
2015-08-14 04:55:37 +00:00
|
|
|
t.Fatalf("bad: %#v", met)
|
|
|
|
}
|
2015-08-14 01:51:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestServiceStack_Select_BinPack_Overflow(t *testing.T) {
|
2015-08-14 04:55:37 +00:00
|
|
|
_, ctx := testContext(t)
|
|
|
|
nodes := []*structs.Node{
|
|
|
|
mock.Node(),
|
|
|
|
mock.Node(),
|
|
|
|
}
|
|
|
|
zero := nodes[0]
|
|
|
|
one := nodes[1]
|
|
|
|
one.Reserved = one.Resources
|
|
|
|
|
2015-08-14 05:35:48 +00:00
|
|
|
stack := NewGenericStack(false, ctx, nodes)
|
2015-08-14 04:55:37 +00:00
|
|
|
|
|
|
|
job := mock.Job()
|
|
|
|
stack.SetJob(job)
|
|
|
|
|
|
|
|
node, _ := stack.Select(job.TaskGroups[0])
|
|
|
|
if node == nil {
|
|
|
|
t.Fatalf("missing node %#v", ctx.Metrics())
|
|
|
|
}
|
|
|
|
|
|
|
|
if node.Node != zero {
|
|
|
|
t.Fatalf("bad")
|
|
|
|
}
|
|
|
|
|
|
|
|
met := ctx.Metrics()
|
|
|
|
if met.NodesExhausted != 1 {
|
|
|
|
t.Fatalf("bad: %#v", met)
|
|
|
|
}
|
2015-08-14 04:58:55 +00:00
|
|
|
if met.ClassExhausted["linux-medium-pci"] != 1 {
|
|
|
|
t.Fatalf("bad: %#v", met)
|
|
|
|
}
|
|
|
|
if len(met.Scores) != 1 {
|
|
|
|
t.Fatalf("bad: %#v", met)
|
|
|
|
}
|
2015-08-14 01:51:08 +00:00
|
|
|
}
|