This is an automated email from the ASF dual-hosted git repository.

mani pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/yunikorn-core.git


The following commit(s) were added to refs/heads/master by this push:
     new cfa8a8d4 [YUNIKORN-2570] Add test cases to break the current 
preemption flow (#847)
cfa8a8d4 is described below

commit cfa8a8d442974f50fe20757fdd9257412dc0fc0b
Author: Manikandan R <[email protected]>
AuthorDate: Mon May 13 11:37:56 2024 +0530

    [YUNIKORN-2570] Add test cases to break the current preemption flow (#847)
    
    Closes: #847
    
    Signed-off-by: Manikandan R <[email protected]>
---
 pkg/scheduler/objects/preemption_test.go | 1193 ++++++++++++++++++++++++++++++
 1 file changed, 1193 insertions(+)

diff --git a/pkg/scheduler/objects/preemption_test.go 
b/pkg/scheduler/objects/preemption_test.go
index 2b0bf7aa..009995e1 100644
--- a/pkg/scheduler/objects/preemption_test.go
+++ b/pkg/scheduler/objects/preemption_test.go
@@ -19,6 +19,7 @@
 package objects
 
 import (
+       "strconv"
        "testing"
        "time"
 
@@ -29,6 +30,10 @@ import (
        "github.com/apache/yunikorn-core/pkg/plugins"
 )
 
+const appID3 = "app-3"
+const alloc = "alloc"
+const node1 = "node1"
+
 func TestCheckPreconditions(t *testing.T) {
        node := newNode("node1", map[string]resources.Quantity{"first": 5})
        iterator := getNodeIteratorFn(node)
@@ -226,6 +231,1194 @@ func TestTryPreemption(t *testing.T) {
        assert.Check(t, !alloc2.IsPreempted(), "alloc2 not preempted")
 }
 
+// TestTryPreemptionOnNode Test try preemption on node with simple queue 
hierarchy. Since Node doesn't have enough resources to accomodate, preemption 
happens because of node resource constraint.
+// Guaranteed and Max resource set on both victim queue path and preemptor 
queue path in 2 levels. victim and preemptor queue are siblings.
+// Ask (Preemptor) resource type matches with all resource types of the 
victim. But Guaranteed set only on specific resource type. 2 Victims are 
available, but 1 should be preempted because further preemption would make 
usage go below the guaranteed quota
+// Setup:
+// Nodes are Node1 and Node2. Nodes are full. No space to accommodate the ask.
+// root.parent. Guaranteed set on parent, first: 10
+// root.parent.child1. Guaranteed set, first: 5. 2 Allocations (belongs to 
single app) are running. Each Allocation usage is first:5, pods: 1. Total usage 
is first:10, pods: 2.
+// root.parent.child2. Guaranteed set, first: 5. Ask of first:5 is waiting for 
resources.
+// 1 Allocation on root.parent.child1 should be preempted to free up resources 
for ask arrived in root.parent.child2.
+func TestTryPreemptionOnNode(t *testing.T) {
+       t.SkipNow()
+       node1 := newNode("node1", map[string]resources.Quantity{"first": 5, 
"pods": 1})
+       node2 := newNode("node2", map[string]resources.Quantity{"first": 5, 
"pods": 1})
+       iterator := getNodeIteratorFn(node1, node2)
+       rootQ, err := createRootQueue(nil)
+       assert.NilError(t, err)
+       parentQ, err := createManagedQueueGuaranteed(rootQ, "parent", true, 
map[string]string{"first": "20"}, map[string]string{"first": "10"})
+       assert.NilError(t, err)
+       childQ1, err := createManagedQueueGuaranteed(parentQ, "child1", false, 
map[string]string{"first": "10"}, map[string]string{"first": "5"})
+       assert.NilError(t, err)
+       childQ2, err := createManagedQueueGuaranteed(parentQ, "child2", false, 
map[string]string{"first": "10"}, map[string]string{"first": "5"})
+       assert.NilError(t, err)
+       app1 := newApplication(appID1, "default", "root.parent.child1")
+       app1.SetQueue(childQ1)
+       childQ1.applications[appID1] = app1
+       ask1 := newAllocationAsk("alloc1", appID1, 
resources.NewResourceFromMap(map[string]resources.Quantity{"first": 5, "pods": 
1}))
+       ask1.createTime = time.Now().Add(-1 * time.Minute)
+       assert.NilError(t, app1.AddAllocationAsk(ask1))
+       ask2 := newAllocationAsk("alloc2", appID1, 
resources.NewResourceFromMap(map[string]resources.Quantity{"first": 5, "pods": 
1}))
+       ask2.createTime = time.Now()
+       assert.NilError(t, app1.AddAllocationAsk(ask2))
+       alloc1 := NewAllocation("node1", ask1)
+       app1.AddAllocation(alloc1)
+       assert.Check(t, node1.AddAllocation(alloc1), "node alloc1 failed")
+       alloc2 := NewAllocation("node1", ask2)
+       app1.AddAllocation(alloc2)
+       assert.Check(t, node2.AddAllocation(alloc2), "node alloc2 failed")
+       assert.NilError(t, 
childQ1.IncAllocatedResource(ask1.GetAllocatedResource(), false))
+       assert.NilError(t, 
childQ1.IncAllocatedResource(ask2.GetAllocatedResource(), false))
+       app2 := newApplication(appID2, "default", "root.parent.child2")
+       app2.SetQueue(childQ2)
+       childQ2.applications[appID2] = app2
+       ask3 := newAllocationAsk("alloc3", appID2, 
resources.NewResourceFromMap(map[string]resources.Quantity{"first": 5, "pods": 
1}))
+       assert.NilError(t, app2.AddAllocationAsk(ask3))
+       headRoom := 
resources.NewResourceFromMap(map[string]resources.Quantity{"first": 10, "pods": 
3})
+       preemptor := NewPreemptor(app2, headRoom, 30*time.Second, ask3, 
iterator(), false)
+
+       alloc, ok := preemptor.TryPreemption()
+       assert.Assert(t, ok, "no victims found")
+       assert.Equal(t, "alloc3", alloc.allocationKey, "wrong alloc")
+       assert.Check(t, !alloc1.IsPreempted(), "alloc1 preempted")
+       assert.Check(t, alloc2.IsPreempted(), "alloc2 not preempted")
+}
+
+// TestTryPreemptionOnQueue Test try preemption on queue with simple queue 
hierarchy. Since Node has enough resources to accomodate, preemption happens 
because of queue resource constraint.
+// Guaranteed and Max resource set on both victim queue path and preemptor 
queue path in 2 levels. victim and preemptor queue are siblings.
+// Ask (Preemptor) resource type matches with all resource types of the 
victim. But Guaranteed set only on specific resource type. 2 Victims are 
available, but 1 should be preempted because further preemption would make 
usage go below the guaranteed quota
+// Setup:
+// Nodes are Node1 and Node2. Node has enough space to accommodate the new ask.
+// root.parent. Guaranteed set on parent, first: 10
+// root.parent.child1. Guaranteed set, first: 5. 2 Allocations (belongs to 
single app) are running. Each Allocation usage is first:5, pods: 1. Total usage 
is first:10, pods: 2.
+// root.parent.child2. Guaranteed set, first: 5. Ask of first:5 is waiting for 
resources.
+// 1 Allocation on root.parent.child1 should be preempted to free up resources 
for ask arrived in root.parent.child2.
+func TestTryPreemptionOnQueue(t *testing.T) {
+       t.SkipNow()
+       node1 := newNode("node1", map[string]resources.Quantity{"first": 10, 
"pods": 2})
+       node2 := newNode("node2", map[string]resources.Quantity{"first": 10, 
"pods": 2})
+       iterator := getNodeIteratorFn(node1, node2)
+       rootQ, err := createRootQueue(nil)
+       assert.NilError(t, err)
+       parentQ, err := createManagedQueueGuaranteed(rootQ, "parent", true, 
map[string]string{"first": "10"}, nil)
+       assert.NilError(t, err)
+       childQ1, err := createManagedQueueGuaranteed(parentQ, "child1", false, 
nil, map[string]string{"first": "5"})
+       assert.NilError(t, err)
+       childQ2, err := createManagedQueueGuaranteed(parentQ, "child2", false, 
nil, map[string]string{"first": "5"})
+       assert.NilError(t, err)
+       app1 := newApplication(appID1, "default", "root.parent.child1")
+       app1.SetQueue(childQ1)
+       childQ1.applications[appID1] = app1
+       ask1 := newAllocationAsk("alloc1", appID1, 
resources.NewResourceFromMap(map[string]resources.Quantity{"first": 5, "pods": 
1}))
+       ask1.createTime = time.Now().Add(-1 * time.Minute)
+       assert.NilError(t, app1.AddAllocationAsk(ask1))
+       ask2 := newAllocationAsk("alloc2", appID1, 
resources.NewResourceFromMap(map[string]resources.Quantity{"first": 5, "pods": 
1}))
+       ask2.createTime = time.Now()
+       assert.NilError(t, app1.AddAllocationAsk(ask2))
+       alloc1 := NewAllocation("node1", ask1)
+       app1.AddAllocation(alloc1)
+       assert.Check(t, node1.AddAllocation(alloc1), "node alloc1 failed")
+       alloc2 := NewAllocation("node1", ask2)
+       app1.AddAllocation(alloc2)
+       assert.Check(t, node2.AddAllocation(alloc2), "node alloc2 failed")
+       assert.NilError(t, 
childQ1.IncAllocatedResource(ask1.GetAllocatedResource(), false))
+       assert.NilError(t, 
childQ1.IncAllocatedResource(ask2.GetAllocatedResource(), false))
+       app2 := newApplication(appID2, "default", "root.parent.child2")
+       app2.SetQueue(childQ2)
+       childQ2.applications[appID2] = app2
+       ask3 := newAllocationAsk("alloc3", appID2, 
resources.NewResourceFromMap(map[string]resources.Quantity{"first": 5, "pods": 
1}))
+       assert.NilError(t, app2.AddAllocationAsk(ask3))
+       headRoom := 
resources.NewResourceFromMap(map[string]resources.Quantity{"first": 10, "pods": 
3})
+       preemptor := NewPreemptor(app2, headRoom, 30*time.Second, ask3, 
iterator(), false)
+
+       alloc, ok := preemptor.TryPreemption()
+       assert.Assert(t, ok, "no victims found")
+       assert.Equal(t, "alloc3", alloc.allocationKey, "wrong alloc")
+       assert.Check(t, !alloc1.IsPreempted(), "alloc1 preempted")
+       assert.Check(t, alloc2.IsPreempted(), "alloc2 not preempted")
+}
+
+// TestTryPreemption_VictimsAvailable_InsufficientResource Test try preemption 
on queue with simple queue hierarchy. Since Node has enough resources to 
accomodate, preemption happens because of queue resource constraint.
+// Guaranteed and Max resource set on both victim queue path and preemptor 
queue path. victim and preemptor queue are siblings.
+// Ask (Preemptor) resource type matches with 1 resource type of the victim. 
Guaranteed also set on specific resource type. 2 Victims are available, but 
total resource usage is lesser than ask requirement.
+// Setup:
+// Nodes are Node1 and Node2. Node has enough space to accommodate the new ask.
+// root.parent.Max set on parent, first: 8
+// root.parent.child1. Guaranteed not set. 2 Allocations (belongs to single 
app) are running. Each Allocation usage is first:2, pods: 1. Total usage is 
first:4, pods: 2.
+// root.parent.child2. Guaranteed set, first: 5. Ask of first:5 is waiting for 
resources.
+// 2 Allocation on root.parent.child1 has been found and considered as 
victims. Since victims total resource usage (first: 4) is lesser than ask 
requirment (first: 5), preemption won't help. Hence, victims are dropped.
+func TestTryPreemption_VictimsAvailable_InsufficientResource(t *testing.T) {
+       t.SkipNow()
+       node1 := newNode(node1, map[string]resources.Quantity{"first": 10, 
"pods": 2})
+       node2 := newNode("node2", map[string]resources.Quantity{"first": 10, 
"pods": 2})
+       iterator := getNodeIteratorFn(node1, node2)
+       rootQ, err := createRootQueue(map[string]string{"first": "20", "pods": 
"5"})
+       assert.NilError(t, err)
+       parentQ, err := createManagedQueueGuaranteed(rootQ, "parent", true, 
map[string]string{"first": "8"}, nil)
+       assert.NilError(t, err)
+       childQ1, err := createManagedQueueGuaranteed(parentQ, "child1", false, 
nil, nil)
+       assert.NilError(t, err)
+       childQ2, err := createManagedQueueGuaranteed(parentQ, "child2", false, 
nil, map[string]string{"first": "5"})
+       assert.NilError(t, err)
+       app1 := newApplication(appID1, "default", "root.parent.child1")
+       app1.SetQueue(childQ1)
+       childQ1.applications[appID1] = app1
+       ask1 := newAllocationAsk("alloc1", appID1, 
resources.NewResourceFromMap(map[string]resources.Quantity{"first": 2, "pods": 
1}))
+       ask1.createTime = time.Now().Add(-1 * time.Minute)
+       assert.NilError(t, app1.AddAllocationAsk(ask1))
+       ask2 := newAllocationAsk("alloc2", appID1, 
resources.NewResourceFromMap(map[string]resources.Quantity{"first": 2, "pods": 
1}))
+       ask2.createTime = time.Now()
+       assert.NilError(t, app1.AddAllocationAsk(ask2))
+       alloc1 := NewAllocation("node1", ask1)
+       app1.AddAllocation(alloc1)
+       assert.Check(t, node1.AddAllocation(alloc1), "node alloc1 failed")
+       alloc2 := NewAllocation("node1", ask2)
+       app1.AddAllocation(alloc2)
+       assert.Check(t, node2.AddAllocation(alloc2), "node alloc2 failed")
+       assert.NilError(t, 
childQ1.IncAllocatedResource(ask1.GetAllocatedResource(), false))
+       assert.NilError(t, 
childQ1.IncAllocatedResource(ask2.GetAllocatedResource(), false))
+       app2 := newApplication(appID2, "default", "root.parent.child2")
+       app2.SetQueue(childQ2)
+       childQ2.applications[appID2] = app2
+       ask3 := newAllocationAsk("alloc3", appID2, 
resources.NewResourceFromMap(map[string]resources.Quantity{"first": 5}))
+       assert.NilError(t, app2.AddAllocationAsk(ask3))
+       headRoom := 
resources.NewResourceFromMap(map[string]resources.Quantity{"first": 10, "pods": 
3})
+       preemptor := NewPreemptor(app2, headRoom, 30*time.Second, ask3, 
iterator(), false)
+
+       alloc, ok := preemptor.TryPreemption()
+       var expectedAlloc *Allocation
+       assert.Equal(t, ok, false, "no victims found")
+       assert.Equal(t, alloc, expectedAlloc, "wrong alloc")
+       assert.Check(t, !alloc1.IsPreempted(), "alloc1 preempted")
+       assert.Check(t, !alloc2.IsPreempted(), "alloc2 not preempted")
+}
+
+// TestTryPreemption_VictimsOnDifferentNodes_InsufficientResource Test try 
preemption on queue with simple queue hierarchy. Since Node doesn't have enough 
resources to accomodate, preemption happens because of node resource constraint.
+// Guaranteed and Max resource set on both victim queue path and preemptor 
queue path. victim and preemptor queue are siblings.
+// Ask (Preemptor) resource type matches with 1 resource type of the victim. 
Guaranteed also set on specific resource type. 2 Victims are available, but 
total resource usage is lesser than ask requirement.
+// Setup:
+// Nodes are Node1 and Node2. Both Nodes are almost full. No space to 
accommodate the ask.
+// root.parent.Max set on parent, first: 6
+// root.parent.child1. Guaranteed not set. 2 Allocations (belongs to single 
app) are running. Each Allocation usage is first:2, pods: 1. Total usage is 
first:4, pods: 2.
+// root.parent.child2. Guaranteed set, first: 5. Ask of first:5 is waiting for 
resources.
+// 2 Allocation on root.parent.child1 has been found and considered as 
victims. Since victims total resource usage (first: 4) is lesser than ask 
requirment (first: 5), preemption won't help. Hence, victims are dropped.
+func TestTryPreemption_VictimsOnDifferentNodes_InsufficientResource(t 
*testing.T) {
+       t.SkipNow()
+       node1 := newNode(node1, map[string]resources.Quantity{"first": 5, 
"pods": 1})
+       node2 := newNode("node2", map[string]resources.Quantity{"first": 5, 
"pods": 1})
+       iterator := getNodeIteratorFn(node1, node2)
+       rootQ, err := createRootQueue(nil)
+       assert.NilError(t, err)
+       parentQ, err := createManagedQueueGuaranteed(rootQ, "parent", true, 
map[string]string{"first": "6"}, nil)
+       assert.NilError(t, err)
+       childQ1, err := createManagedQueueGuaranteed(parentQ, "child1", false, 
nil, nil)
+       assert.NilError(t, err)
+       childQ2, err := createManagedQueueGuaranteed(parentQ, "child2", false, 
nil, map[string]string{"first": "5"})
+       assert.NilError(t, err)
+       app1 := newApplication(appID1, "default", "root.parent.child1")
+       app1.SetQueue(childQ1)
+       childQ1.applications[appID1] = app1
+       ask1 := newAllocationAsk("alloc1", appID1, 
resources.NewResourceFromMap(map[string]resources.Quantity{"first": 2, "pods": 
1}))
+       ask1.createTime = time.Now().Add(-1 * time.Minute)
+       assert.NilError(t, app1.AddAllocationAsk(ask1))
+       ask2 := newAllocationAsk("alloc2", appID1, 
resources.NewResourceFromMap(map[string]resources.Quantity{"first": 2, "pods": 
1}))
+       ask2.createTime = time.Now()
+       assert.NilError(t, app1.AddAllocationAsk(ask2))
+       alloc1 := NewAllocation("node1", ask1)
+       app1.AddAllocation(alloc1)
+       assert.Check(t, node1.AddAllocation(alloc1), "node alloc1 failed")
+       alloc2 := NewAllocation("node2", ask2)
+       app1.AddAllocation(alloc2)
+       assert.Check(t, node2.AddAllocation(alloc2), "node alloc2 failed")
+       assert.NilError(t, 
childQ1.IncAllocatedResource(ask1.GetAllocatedResource(), false))
+       assert.NilError(t, 
childQ1.IncAllocatedResource(ask2.GetAllocatedResource(), false))
+       app2 := newApplication(appID2, "default", "root.parent.child2")
+       app2.SetQueue(childQ2)
+       childQ2.applications[appID2] = app2
+       ask3 := newAllocationAsk("alloc3", appID2, 
resources.NewResourceFromMap(map[string]resources.Quantity{"first": 5}))
+       assert.NilError(t, app2.AddAllocationAsk(ask3))
+       headRoom := 
resources.NewResourceFromMap(map[string]resources.Quantity{"first": 10, "pods": 
3})
+       preemptor := NewPreemptor(app2, headRoom, 30*time.Second, ask3, 
iterator(), false)
+
+       // register predicate handler
+       preemptions := []mock.Preemption{
+               mock.NewPreemption(true, "alloc3", "node1", []string{"alloc1"}, 
0, 0),
+               mock.NewPreemption(true, "alloc3", "node2", []string{"alloc2"}, 
0, 0),
+       }
+
+       plugin := mock.NewPreemptionPredicatePlugin(nil, nil, preemptions)
+       plugins.RegisterSchedulerPlugin(plugin)
+       defer plugins.UnregisterSchedulerPlugins()
+
+       alloc, ok := preemptor.TryPreemption()
+       var expectedAlloc *Allocation
+       assert.Equal(t, ok, false, "no victims found")
+       assert.Equal(t, alloc, expectedAlloc, "wrong alloc")
+       assert.Check(t, !alloc1.IsPreempted(), "alloc1 preempted")
+       assert.Check(t, !alloc2.IsPreempted(), "alloc2 not preempted")
+}
+
+// TestTryPreemption_VictimsAvailableOnDifferentNodes Test try preemption on 
queue with simple queue hierarchy. Since Node doesn't have enough resources to 
accomodate, preemption happens because of node resource constraint.
+// Guaranteed and Max resource set on both victim queue path and preemptor 
queue path. victim and preemptor queue are siblings.
+// Ask (Preemptor) resource type matches with 1 resource type of the victim. 
Guaranteed also set on specific resource type. 2 Victims are available, but 
total resource usage is lesser than ask requirement.
+// Setup:
+// Nodes are Node1 and Node2. Both Nodes are almost full. No space to 
accommodate the ask. Node 2 won't even fit because max capacity itself is 
lesser than ask requirement. Hence, Node 1 only is eligible.
+// root.parent.Max set on parent, first: 6
+// root.parent.child1. Guaranteed not set. 2 Allocations (belongs to single 
app) are running. 1st Allocation usage is first:4, pods: 1. 2nd Allocation 
usage is first:2, pods: 1. Total usage is first:6, pods: 2.
+// root.parent.child2. Guaranteed set, first: 5. Ask of first:5 is waiting for 
resources.
+// 2 Allocation on root.parent.child1 has been found and considered as victims 
and preempted to free up resources for ask.
+func TestTryPreemption_VictimsAvailableOnDifferentNodes(t *testing.T) {
+       t.SkipNow()
+       node1 := newNode(node1, map[string]resources.Quantity{"first": 5, 
"pods": 1})
+       node2 := newNode("node2", map[string]resources.Quantity{"first": 4, 
"pods": 1})
+       iterator := getNodeIteratorFn(node1, node2)
+       rootQ, err := createRootQueue(nil)
+       assert.NilError(t, err)
+       parentQ, err := createManagedQueueGuaranteed(rootQ, "parent", true, 
map[string]string{"first": "6"}, nil)
+       assert.NilError(t, err)
+       childQ1, err := createManagedQueueGuaranteed(parentQ, "child1", false, 
nil, nil)
+       assert.NilError(t, err)
+       childQ2, err := createManagedQueueGuaranteed(parentQ, "child2", false, 
nil, map[string]string{"first": "5"})
+       assert.NilError(t, err)
+       app1 := newApplication(appID1, "default", "root.parent.child1")
+       app1.SetQueue(childQ1)
+       childQ1.applications[appID1] = app1
+       ask1 := newAllocationAsk("alloc1", appID1, 
resources.NewResourceFromMap(map[string]resources.Quantity{"first": 4, "pods": 
1}))
+       ask1.createTime = time.Now().Add(-1 * time.Minute)
+       assert.NilError(t, app1.AddAllocationAsk(ask1))
+       ask2 := newAllocationAsk("alloc2", appID1, 
resources.NewResourceFromMap(map[string]resources.Quantity{"first": 2, "pods": 
1}))
+       ask2.createTime = time.Now()
+       assert.NilError(t, app1.AddAllocationAsk(ask2))
+       alloc1 := NewAllocation("node1", ask1)
+       app1.AddAllocation(alloc1)
+       assert.Check(t, node1.AddAllocation(alloc1), "node alloc1 failed")
+       alloc2 := NewAllocation("node2", ask2)
+       app1.AddAllocation(alloc2)
+       assert.Check(t, node2.AddAllocation(alloc2), "node alloc2 failed")
+       assert.NilError(t, 
childQ1.IncAllocatedResource(ask1.GetAllocatedResource(), false))
+       assert.NilError(t, 
childQ1.IncAllocatedResource(ask2.GetAllocatedResource(), false))
+       app2 := newApplication(appID2, "default", "root.parent.child2")
+       app2.SetQueue(childQ2)
+       childQ2.applications[appID2] = app2
+       ask3 := newAllocationAsk("alloc3", appID2, 
resources.NewResourceFromMap(map[string]resources.Quantity{"first": 5}))
+       assert.NilError(t, app2.AddAllocationAsk(ask3))
+       headRoom := 
resources.NewResourceFromMap(map[string]resources.Quantity{"first": 10, "pods": 
3})
+       preemptor := NewPreemptor(app2, headRoom, 30*time.Second, ask3, 
iterator(), false)
+
+       // register predicate handler
+       preemptions := []mock.Preemption{
+               mock.NewPreemption(true, "alloc3", "node1", []string{"alloc1"}, 
0, 0),
+               mock.NewPreemption(true, "alloc3", "node2", []string{"alloc2"}, 
0, 0),
+       }
+
+       plugin := mock.NewPreemptionPredicatePlugin(nil, nil, preemptions)
+       plugins.RegisterSchedulerPlugin(plugin)
+       defer plugins.UnregisterSchedulerPlugins()
+
+       alloc, ok := preemptor.TryPreemption()
+       assert.Assert(t, ok, "no victims found")
+       assert.Equal(t, "alloc3", alloc.allocationKey, "wrong alloc")
+       assert.Check(t, alloc1.IsPreempted(), "alloc1 preempted")
+       assert.Check(t, alloc2.IsPreempted(), "alloc2 not preempted")
+}
+
+// TestTryPreemption_OnQueue_VictimsOnDifferentNodes Test try preemption on 
queue with simple queue hierarchy. Since Node has enough resources to 
accomodate, preemption happens because of queue resource constraint.
+// Guaranteed and Max resource set on both victim queue path and preemptor 
queue paths. victim and preemptor queue are siblings.
+// Ask (Preemptor) resource type matches with all resource types of the 
victim. Guaranteed set only on that specific resource type.
+// Setup:
+// Nodes are Node1 and Node2. Node has enough space to accommodate the new ask.
+// root.parent. Max set on parent, first: 18
+// root.parent.child1. Guaranteed not set. 2 Allocations (belongs to single 
app) are running on node1 and node2. Each Allocation usage is first:5. Total 
usage is first:10.
+// root.parent.child2. Guaranteed set 5. Ask of first:5 is waiting for 
resources.
+// root.parent.child3. Guaranteed not set. 1 Allocation is running on node2. 
Total usage is first:5.
+// Preemption options are 1. 2 Alloc running on Node 2 but on child 1 and 
child 3 queues.  2. 2 Alloc running on Node 2 and child 1 queue. 3. All three 3 
allocs.
+// option 1 >> option 2 >> option 3. In option 3, preempting third allocation 
is unnecessary, should avoid this option.
+// Either option 1 or option2 is fine, but not option 3.
+func TestTryPreemption_OnQueue_VictimsOnDifferentNodes(t *testing.T) {
+       t.SkipNow()
+       node1 := newNode(node1, map[string]resources.Quantity{"first": 30})
+       node2 := newNode("node2", map[string]resources.Quantity{"first": 30})
+       iterator := getNodeIteratorFn(node1, node2)
+       rootQ, err := createRootQueue(nil)
+       assert.NilError(t, err)
+       parentQ, err := createManagedQueueGuaranteed(rootQ, "parent", true, 
map[string]string{"first": "18"}, nil)
+       assert.NilError(t, err)
+       childQ1, err := createManagedQueueGuaranteed(parentQ, "child1", false, 
nil, nil)
+       assert.NilError(t, err)
+       childQ2, err := createManagedQueueGuaranteed(parentQ, "child2", false, 
nil, map[string]string{"first": "15"})
+       assert.NilError(t, err)
+       childQ3, err := createManagedQueueGuaranteed(parentQ, "child3", false, 
nil, nil)
+       assert.NilError(t, err)
+       app1 := newApplication(appID1, "default", "root.parent.child1")
+       app1.SetQueue(childQ1)
+       childQ1.applications[appID1] = app1
+       ask1 := newAllocationAsk("alloc1", appID1, 
resources.NewResourceFromMap(map[string]resources.Quantity{"first": 5}))
+       ask1.createTime = time.Now().Add(-2 * time.Minute)
+       assert.NilError(t, app1.AddAllocationAsk(ask1))
+       ask2 := newAllocationAsk("alloc2", appID1, 
resources.NewResourceFromMap(map[string]resources.Quantity{"first": 5}))
+       ask2.createTime = time.Now().Add(-1 * time.Minute)
+       assert.NilError(t, app1.AddAllocationAsk(ask2))
+       alloc1 := NewAllocation("node1", ask1)
+       app1.AddAllocation(alloc1)
+       assert.Check(t, node1.AddAllocation(alloc1), "node alloc1 failed")
+       alloc2 := NewAllocation("node2", ask2)
+       app1.AddAllocation(alloc2)
+       assert.Check(t, node2.AddAllocation(alloc2), "node alloc2 failed")
+
+       assert.NilError(t, 
childQ1.IncAllocatedResource(ask1.GetAllocatedResource(), false))
+       assert.NilError(t, 
childQ1.IncAllocatedResource(ask2.GetAllocatedResource(), false))
+
+       app3 := newApplication(appID3, "default", "root.parent.child3")
+       app3.SetQueue(childQ3)
+       childQ3.applications[appID3] = app3
+
+       ask4 := newAllocationAsk("alloc4", appID3, 
resources.NewResourceFromMap(map[string]resources.Quantity{"first": 5}))
+       ask4.createTime = time.Now()
+       assert.NilError(t, app3.AddAllocationAsk(ask4))
+
+       alloc4 := NewAllocation("node2", ask4)
+       app3.AddAllocation(alloc4)
+       assert.Check(t, node2.AddAllocation(alloc4), "node alloc2 failed")
+       assert.NilError(t, 
childQ3.IncAllocatedResource(ask4.GetAllocatedResource(), false))
+
+       app2 := newApplication(appID2, "default", "root.parent.child2")
+       app2.SetQueue(childQ2)
+       childQ2.applications[appID2] = app2
+       ask3 := newAllocationAsk("alloc3", appID2, 
resources.NewResourceFromMap(map[string]resources.Quantity{"first": 10}))
+       assert.NilError(t, app2.AddAllocationAsk(ask3))
+       headRoom := 
resources.NewResourceFromMap(map[string]resources.Quantity{"first": 10, "pods": 
3})
+       preemptor := NewPreemptor(app2, headRoom, 30*time.Second, ask3, 
iterator(), false)
+
+       allocs := map[string]string{}
+       allocs["alloc3"] = "node2"
+
+       plugin := mock.NewPreemptionPredicatePlugin(nil, allocs, nil)
+       plugins.RegisterSchedulerPlugin(plugin)
+       defer plugins.UnregisterSchedulerPlugins()
+
+       alloc, ok := preemptor.TryPreemption()
+       assert.Assert(t, ok, "no victims found")
+       assert.Equal(t, "alloc3", alloc.allocationKey, "wrong alloc")
+       assert.Equal(t, "node2", alloc.nodeID, "wrong alloc")
+       assert.Equal(t, "node1", alloc1.nodeID, "wrong alloc")
+       assert.Equal(t, "node2", alloc2.nodeID, "wrong alloc")
+       assert.Equal(t, "node2", alloc4.nodeID, "wrong alloc")
+       assert.Check(t, !alloc1.IsPreempted(), "alloc1 preempted")
+       assert.Check(t, alloc2.IsPreempted(), "alloc2 not preempted")
+       assert.Check(t, alloc4.IsPreempted(), "alloc2 not preempted")
+}
+
+// TestTryPreemption_OnQueue_VictimsAvailable_LowerPriority Test try 
preemption on queue with simple queue hierarchy. Since Node has enough 
resources to accomodate, preemption happens because of queue resource 
constraint.
+// Guaranteed and Max resource set on both victim queue path and preemptor 
queue paths. victim and preemptor queue are siblings.
+// Ask (Preemptor) resource type matches with all resource types of the 
victim. Guaranteed set only on that specific resource type.
+// Setup:
+// Nodes are Node1 and Node2. Node has enough space to accommodate the new ask.
+// root.parent. Max set on parent, first: 18
+// root.parent.child1. Guaranteed not set. 2 Allocations (belongs to single 
app) are running on node1 and node2. Each Allocation usage is first:5. Total 
usage is first:10.
+// root.parent.child2. Guaranteed set 5. Ask of first:5 is waiting for 
resources.
+// root.parent.child3. Guaranteed not set. 1 Allocation is running on node2. 
Total usage is first:5.
+// High priority ask should not be touched and remaining 2 allocs should be 
preempted to free up resources
+func TestTryPreemption_OnQueue_VictimsAvailable_LowerPriority(t *testing.T) {
+       t.SkipNow()
+       node1 := newNode(node1, map[string]resources.Quantity{"first": 30})
+       node2 := newNode("node2", map[string]resources.Quantity{"first": 30})
+       iterator := getNodeIteratorFn(node1, node2)
+       rootQ, err := createRootQueue(nil)
+       assert.NilError(t, err)
+       parentQ, err := createManagedQueueGuaranteed(rootQ, "parent", true, 
map[string]string{"first": "18"}, nil)
+       assert.NilError(t, err)
+       childQ1, err := createManagedQueueGuaranteed(parentQ, "child1", false, 
nil, nil)
+       assert.NilError(t, err)
+       childQ2, err := createManagedQueueGuaranteed(parentQ, "child2", false, 
nil, map[string]string{"first": "15"})
+       assert.NilError(t, err)
+       childQ3, err := createManagedQueueGuaranteed(parentQ, "child3", false, 
nil, nil)
+       assert.NilError(t, err)
+       app1 := newApplication(appID1, "default", "root.parent.child1")
+       app1.SetQueue(childQ1)
+       childQ1.applications[appID1] = app1
+       ask1 := newAllocationAsk("alloc1", appID1, 
resources.NewResourceFromMap(map[string]resources.Quantity{"first": 5}))
+       ask1.createTime = time.Now().Add(-2 * time.Minute)
+       assert.NilError(t, app1.AddAllocationAsk(ask1))
+
+       // High priority ask, should not be considered as victim
+       ask2 := newAllocationAskPriority("alloc2", appID1, 
resources.NewResourceFromMap(map[string]resources.Quantity{"first": 5}), 1000)
+       ask2.createTime = time.Now().Add(-1 * time.Minute)
+       assert.NilError(t, app1.AddAllocationAsk(ask2))
+       alloc1 := NewAllocation("node1", ask1)
+       app1.AddAllocation(alloc1)
+       assert.Check(t, node1.AddAllocation(alloc1), "node alloc1 failed")
+       alloc2 := NewAllocation("node2", ask2)
+       app1.AddAllocation(alloc2)
+       assert.Check(t, node2.AddAllocation(alloc2), "node alloc2 failed")
+
+       assert.NilError(t, 
childQ1.IncAllocatedResource(ask1.GetAllocatedResource(), false))
+       assert.NilError(t, 
childQ1.IncAllocatedResource(ask2.GetAllocatedResource(), false))
+
+       app3 := newApplication(appID3, "default", "root.parent.child3")
+       app3.SetQueue(childQ3)
+       childQ3.applications[appID3] = app3
+
+       ask4 := newAllocationAsk("alloc4", appID3, 
resources.NewResourceFromMap(map[string]resources.Quantity{"first": 5}))
+       ask4.createTime = time.Now()
+       assert.NilError(t, app3.AddAllocationAsk(ask4))
+
+       alloc4 := NewAllocation("node2", ask4)
+       app3.AddAllocation(alloc4)
+       assert.Check(t, node2.AddAllocation(alloc4), "node alloc2 failed")
+       assert.NilError(t, 
childQ3.IncAllocatedResource(ask4.GetAllocatedResource(), false))
+
+       app2 := newApplication(appID2, "default", "root.parent.child2")
+       app2.SetQueue(childQ2)
+       childQ2.applications[appID2] = app2
+       ask3 := newAllocationAsk("alloc3", appID2, 
resources.NewResourceFromMap(map[string]resources.Quantity{"first": 10}))
+       assert.NilError(t, app2.AddAllocationAsk(ask3))
+       headRoom := 
resources.NewResourceFromMap(map[string]resources.Quantity{"first": 10, "pods": 
3})
+       preemptor := NewPreemptor(app2, headRoom, 30*time.Second, ask3, 
iterator(), false)
+
+       allocs := map[string]string{}
+       allocs["alloc3"] = "node2"
+
+       plugin := mock.NewPreemptionPredicatePlugin(nil, allocs, nil)
+       plugins.RegisterSchedulerPlugin(plugin)
+       defer plugins.UnregisterSchedulerPlugins()
+
+       alloc, ok := preemptor.TryPreemption()
+       assert.Assert(t, ok, "no victims found")
+       assert.Equal(t, "alloc3", alloc.allocationKey, "wrong alloc")
+       assert.Equal(t, "node2", alloc.nodeID, "wrong alloc")
+       assert.Equal(t, "node1", alloc1.nodeID, "wrong alloc")
+       assert.Equal(t, "node2", alloc2.nodeID, "wrong alloc")
+       assert.Equal(t, "node2", alloc4.nodeID, "wrong alloc")
+       assert.Check(t, alloc1.IsPreempted(), "alloc1 preempted")
+       assert.Check(t, !alloc2.IsPreempted(), "alloc2 not preempted")
+       assert.Check(t, alloc4.IsPreempted(), "alloc2 not preempted")
+}
+
+// TestTryPreemption_AskResTypesDifferent_GuaranteedSetOnPreemptorSide Test 
try preemption with 2 level queue hierarchy.
+// Guaranteed set only on preemptor queue path, but not on the victim queue 
path.
+// Ask (Preemptor) resource type matches with one of the victim's resource 
types.  Still, needs to be preempted because matching resource type has been 
configured as guaranteed.
+// Setup:
+// Nodes are Node1. Node has enough space to accommodate the new ask.
+// root.parent.parent1.child1. Guaranteed set on root.parent.parent1, vcores: 
1. Ask of vcores: 1 is waiting for resources.
+// root.parent.parent2.child2. 2 Allocations (belongs to single app) are 
running. Each Allocation usage is vcores:1, mem: 200. Total usage is vcores:2, 
mem: 400
+// root.parent.parent2.child3. No usage, no guaranteed set
+// 1 Allocation on root.parent.parent1.child2 should be preempted to free up 
resources for ask arrived in root.parent.parent1.child1.
+func TestTryPreemption_AskResTypesDifferent_GuaranteedSetOnPreemptorSide(t 
*testing.T) {
+       t.SkipNow()
+       node := newNode(node1, map[string]resources.Quantity{"vcores": 3, 
"mem": 400})
+       iterator := getNodeIteratorFn(node)
+       rootQ, err := createRootQueue(nil)
+       assert.NilError(t, err)
+       parentQ, err := createManagedQueueGuaranteed(rootQ, "parent", true, 
map[string]string{"vcores": "2"}, nil)
+       assert.NilError(t, err)
+       parentQ1, err := createManagedQueueGuaranteed(parentQ, "parent1", true, 
nil, map[string]string{"vcores": "1"})
+       assert.NilError(t, err)
+       parentQ2, err := createManagedQueueGuaranteed(parentQ, "parent2", true, 
nil, nil)
+       assert.NilError(t, err)
+
+       childQ1, err := createManagedQueueGuaranteed(parentQ1, "child1", false, 
nil, nil)
+       assert.NilError(t, err)
+       childQ2, err := createManagedQueueGuaranteed(parentQ2, "child2", false, 
nil, nil)
+       assert.NilError(t, err)
+       _, err = createManagedQueueGuaranteed(parentQ2, "child3", false, nil, 
nil)
+       assert.NilError(t, err)
+
+       app1 := newApplication(appID1, "default", "root.parent.parent2.child2")
+       app1.SetQueue(childQ2)
+       childQ2.applications[appID1] = app1
+       ask1 := newAllocationAsk("alloc1", appID1, 
resources.NewResourceFromMap(map[string]resources.Quantity{"vcores": 1, "mem": 
200}))
+       ask1.createTime = time.Now().Add(-1 * time.Minute)
+       assert.NilError(t, app1.AddAllocationAsk(ask1))
+       ask2 := newAllocationAsk("alloc2", appID1, 
resources.NewResourceFromMap(map[string]resources.Quantity{"vcores": 1, "mem": 
200}))
+       ask2.createTime = time.Now()
+       assert.NilError(t, app1.AddAllocationAsk(ask2))
+       alloc1 := NewAllocation(node1, ask1)
+       app1.AddAllocation(alloc1)
+       assert.Check(t, node.AddAllocation(alloc1), "node alloc1 failed")
+       alloc2 := NewAllocation(node1, ask2)
+       app1.AddAllocation(alloc2)
+       assert.Check(t, node.AddAllocation(alloc2), "node alloc2 failed")
+       assert.NilError(t, 
childQ2.IncAllocatedResource(ask1.GetAllocatedResource(), false))
+       assert.NilError(t, 
childQ2.IncAllocatedResource(ask2.GetAllocatedResource(), false))
+       app2 := newApplication(appID2, "default", "root.parent.parent1.child1")
+       app2.SetQueue(childQ1)
+       childQ1.applications[appID2] = app2
+       ask3 := newAllocationAsk("alloc3", appID2, 
resources.NewResourceFromMap(map[string]resources.Quantity{"vcores": 1}))
+       assert.NilError(t, app2.AddAllocationAsk(ask3))
+       headRoom := 
resources.NewResourceFromMap(map[string]resources.Quantity{"vcores": 2})
+       preemptor := NewPreemptor(app2, headRoom, 30*time.Second, ask3, 
iterator(), false)
+
+       alloc, ok := preemptor.TryPreemption()
+       assert.Assert(t, ok, "no victims found")
+       assert.Equal(t, "alloc3", alloc.allocationKey, "wrong alloc")
+       assert.Check(t, !alloc1.IsPreempted(), "alloc1 preempted")
+       assert.Check(t, alloc2.IsPreempted(), "alloc2 not preempted")
+}
+
+// TestTryPreemption_OnNode_AskResTypesDifferent_GuaranteedSetOnPreemptorSide 
Test try preemption with 2 level queue hierarchy. Since Node doesn't have 
enough resources to accomodate, preemption happens because of node resource 
constraint.
+// Guaranteed set only on preemptor queue path, but not on the victim queue 
path.
+// Ask (Preemptor) resource type matches with one of the victim's resource 
types.  Still, needs to be preempted because matching resource type has been 
configured as guaranteed.
+// Setup:
+// Nodes are Node1. Node is full, doesn't enough space to accommodate the ask.
+// root.parent.parent1.child1. Guaranteed set on root.parent.parent1, vcores: 
1. Ask of vcores: 1 is waiting for resources.
+// root.parent.parent2.child2. 2 Allocations (belongs to single app) are 
running. Each Allocation usage is vcores:1, mem: 200. Total usage is vcores:2, 
mem: 400
+// root.parent.parent2.child3. No usage, no guaranteed set
+// 1 Allocation on root.parent.parent1.child2 should be preempted to free up 
resources for ask arrived in root.parent.parent1.child1.
+func 
TestTryPreemption_OnNode_AskResTypesDifferent_GuaranteedSetOnPreemptorSide(t 
*testing.T) {
+       t.SkipNow()
+       node := newNode(node1, map[string]resources.Quantity{"vcores": 2, 
"mem": 400})
+       iterator := getNodeIteratorFn(node)
+       rootQ, err := createRootQueue(nil)
+       assert.NilError(t, err)
+       parentQ, err := createManagedQueueGuaranteed(rootQ, "parent", true, 
map[string]string{"vcores": "2"}, nil)
+       assert.NilError(t, err)
+       parentQ1, err := createManagedQueueGuaranteed(parentQ, "parent1", true, 
nil, map[string]string{"vcores": "1"})
+       assert.NilError(t, err)
+       parentQ2, err := createManagedQueueGuaranteed(parentQ, "parent2", true, 
nil, nil)
+       assert.NilError(t, err)
+
+       childQ1, err := createManagedQueueGuaranteed(parentQ1, "child1", false, 
nil, nil)
+       assert.NilError(t, err)
+       childQ2, err := createManagedQueueGuaranteed(parentQ2, "child2", false, 
nil, nil)
+       assert.NilError(t, err)
+       _, err = createManagedQueueGuaranteed(parentQ2, "child3", false, nil, 
nil)
+       assert.NilError(t, err)
+
+       app1 := newApplication(appID1, "default", "root.parent.parent2.child2")
+       app1.SetQueue(childQ2)
+       childQ2.applications[appID1] = app1
+       ask1 := newAllocationAsk("alloc1", appID1, 
resources.NewResourceFromMap(map[string]resources.Quantity{"vcores": 1, "mem": 
200}))
+       ask1.createTime = time.Now().Add(-1 * time.Minute)
+       assert.NilError(t, app1.AddAllocationAsk(ask1))
+       ask2 := newAllocationAsk("alloc2", appID1, 
resources.NewResourceFromMap(map[string]resources.Quantity{"vcores": 1, "mem": 
200}))
+       ask2.createTime = time.Now()
+       assert.NilError(t, app1.AddAllocationAsk(ask2))
+       alloc1 := NewAllocation(node1, ask1)
+       app1.AddAllocation(alloc1)
+       assert.Check(t, node.AddAllocation(alloc1), "node alloc1 failed")
+       alloc2 := NewAllocation(node1, ask2)
+       app1.AddAllocation(alloc2)
+       assert.Check(t, node.AddAllocation(alloc2), "node alloc2 failed")
+       assert.NilError(t, 
childQ2.IncAllocatedResource(ask1.GetAllocatedResource(), false))
+       assert.NilError(t, 
childQ2.IncAllocatedResource(ask2.GetAllocatedResource(), false))
+       app2 := newApplication(appID2, "default", "root.parent.parent1.child1")
+       app2.SetQueue(childQ1)
+       childQ1.applications[appID2] = app2
+       ask3 := newAllocationAsk("alloc3", appID2, 
resources.NewResourceFromMap(map[string]resources.Quantity{"vcores": 1}))
+       assert.NilError(t, app2.AddAllocationAsk(ask3))
+       headRoom := 
resources.NewResourceFromMap(map[string]resources.Quantity{"vcores": 2})
+       preemptor := NewPreemptor(app2, headRoom, 30*time.Second, ask3, 
iterator(), false)
+
+       // register predicate handler
+       preemptions := []mock.Preemption{mock.NewPreemption(true, "alloc3", 
node1, []string{"alloc2"}, 0, 0)}
+       plugin := mock.NewPreemptionPredicatePlugin(nil, nil, preemptions)
+       plugins.RegisterSchedulerPlugin(plugin)
+       defer plugins.UnregisterSchedulerPlugins()
+
+       alloc, ok := preemptor.TryPreemption()
+       assert.Assert(t, ok, "no victims found")
+       assert.Equal(t, "alloc3", alloc.allocationKey, "wrong alloc")
+       assert.Check(t, !alloc1.IsPreempted(), "alloc1 preempted")
+       assert.Check(t, alloc2.IsPreempted(), "alloc2 not preempted")
+}
+
+// 
TestTryPreemption_AskResTypesDifferent_GuaranteedSetOnVictimAndPreemptorSides 
Test try preemption with 2 level queue hierarchy.
+// Guaranteed set on both victim queue path and preemptor queue path.
+// Ask (Preemptor) resource type matches with one of the victim's resource 
types.  Still, needs to be preempted because matching resource type has been 
configured as guaranteed.
+// Setup:
+// Nodes are Node1. Node has enough space to accommodate the new ask.
+// root.parent.parent1.child1. Guaranteed set on parent1, vcores: 2. Ask of 
vcores: 1 is waiting for resources.
+// root.parent.parent2.child2. Guaranteed set on parent2, vcores: 1. 6 
Allocations (belongs to two diff apps) are running. 3 Allocation's usage is 
vcores:1, mem: 100. 3 more allocations usage is mem: 100. Total usage is 
vcores:3, mem: 600
+// root.parent.parent2.child3. No usage, no guaranteed set
+// 2 Allocations of each vcores:1, mem: 100 running on 
root.parent.parent1.child2 should be preempted to free up resources for ask 
arrived in root.parent.parent1.child1.
+// 3rd allocation of vcores:1, mem: 100 should not be touched as preempting 
the same would make usage goes below the guaranteed set on 
root.parent.parent2.child2.
+// All remaining three allocation of each mem: 100 should not be touched at 
all as there is no matching resource type between these allocs and ask resource 
types.
+func 
TestTryPreemption_AskResTypesDifferent_GuaranteedSetOnVictimAndPreemptorSides(t 
*testing.T) {
+       t.SkipNow()
+       node := newNode(node1, map[string]resources.Quantity{"vcores": 5, 
"mem": 700})
+       iterator := getNodeIteratorFn(node)
+       rootQ, err := createRootQueue(nil)
+       assert.NilError(t, err)
+       parentQ, err := createManagedQueueGuaranteed(rootQ, "parent", true, 
map[string]string{"vcores": "3"}, nil)
+       assert.NilError(t, err)
+       parentQ1, err := createManagedQueueGuaranteed(parentQ, "parent1", true, 
nil, nil)
+       assert.NilError(t, err)
+       parentQ2, err := createManagedQueueGuaranteed(parentQ, "parent2", true, 
nil, nil)
+       assert.NilError(t, err)
+
+       childQ1, err := createManagedQueueGuaranteed(parentQ1, "child1", false, 
nil, map[string]string{"vcores": "2"})
+       assert.NilError(t, err)
+       childQ2, err := createManagedQueueGuaranteed(parentQ2, "child2", false, 
nil, map[string]string{"vcores": "1"})
+       assert.NilError(t, err)
+       _, err = createManagedQueueGuaranteed(parentQ2, "child3", false, nil, 
nil)
+       assert.NilError(t, err)
+
+       app1 := newApplication(appID1, "default", "root.parent.parent2.child2")
+       app1.SetQueue(childQ2)
+       childQ2.applications[appID1] = app1
+       app2 := newApplication(appID2, "default", "root.parent.parent2.child2")
+       app2.SetQueue(childQ2)
+       childQ2.applications[appID2] = app2
+       app3 := newApplication(appID3, "default", "root.parent.parent2.child2")
+       app3.SetQueue(childQ2)
+       childQ2.applications[appID3] = app3
+
+       for i := 5; i < 8; i++ {
+               askN := newAllocationAsk(alloc+strconv.Itoa(i), appID1, 
resources.NewResourceFromMap(map[string]resources.Quantity{"mem": 100}))
+               askN.createTime = time.Now().Add(-2 * time.Minute)
+               assert.NilError(t, app1.AddAllocationAsk(askN))
+               allocN := NewAllocation(node1, askN)
+               app1.AddAllocation(allocN)
+               assert.Check(t, node.AddAllocation(allocN), "node alloc1 
failed")
+       }
+
+       ask1 := newAllocationAsk("alloc1", appID1, 
resources.NewResourceFromMap(map[string]resources.Quantity{"vcores": 1, "mem": 
100}))
+       ask1.createTime = time.Now().Add(-1 * time.Minute)
+       assert.NilError(t, app1.AddAllocationAsk(ask1))
+       ask2 := newAllocationAsk("alloc2", appID2, 
resources.NewResourceFromMap(map[string]resources.Quantity{"vcores": 1, "mem": 
100}))
+       ask2.createTime = time.Now()
+       assert.NilError(t, app1.AddAllocationAsk(ask2))
+       ask3 := newAllocationAsk("alloc3", appID2, 
resources.NewResourceFromMap(map[string]resources.Quantity{"vcores": 1, "mem": 
100}))
+       ask3.createTime = time.Now()
+       assert.NilError(t, app1.AddAllocationAsk(ask3))
+       alloc1 := NewAllocation(node1, ask1)
+       app1.AddAllocation(alloc1)
+       assert.Check(t, node.AddAllocation(alloc1), "node alloc1 failed")
+       alloc2 := NewAllocation(node1, ask2)
+       app2.AddAllocation(alloc2)
+       assert.Check(t, node.AddAllocation(alloc2), "node alloc2 failed")
+       alloc3 := NewAllocation(node1, ask3)
+       app3.AddAllocation(alloc3)
+       assert.Check(t, node.AddAllocation(alloc3), "node alloc3 failed")
+
+       for i := 5; i < 8; i++ {
+               assert.NilError(t, 
childQ2.IncAllocatedResource(resources.NewResourceFromMap(map[string]resources.Quantity{"mem":
 100}), false))
+       }
+       assert.NilError(t, 
childQ2.IncAllocatedResource(ask1.GetAllocatedResource(), false))
+       assert.NilError(t, 
childQ2.IncAllocatedResource(ask2.GetAllocatedResource(), false))
+       assert.NilError(t, 
childQ2.IncAllocatedResource(ask3.GetAllocatedResource(), false))
+
+       app4 := newApplication("app-4", "default", "root.parent.parent1.child1")
+       app4.SetQueue(childQ1)
+       ask4 := newAllocationAsk("alloc4", "app-4", 
resources.NewResourceFromMap(map[string]resources.Quantity{"vcores": 2}))
+       assert.NilError(t, app4.AddAllocationAsk(ask4))
+       headRoom := 
resources.NewResourceFromMap(map[string]resources.Quantity{"vcores": 2})
+       preemptor := NewPreemptor(app4, headRoom, 30*time.Second, ask4, 
iterator(), false)
+
+       // register predicate handler
+       preemptions := []mock.Preemption{mock.NewPreemption(true, "alloc4", 
node1, []string{"alloc3", "alloc2"}, 1, 1)}
+       allocs := map[string]string{}
+       allocs["alloc4"] = node1
+       plugin := mock.NewPreemptionPredicatePlugin(nil, allocs, preemptions)
+       plugins.RegisterSchedulerPlugin(plugin)
+       defer plugins.UnregisterSchedulerPlugins()
+
+       alloc, ok := preemptor.TryPreemption()
+       assert.NilError(t, plugin.GetPredicateError())
+       assert.Assert(t, ok, "no victims found")
+       assert.Equal(t, "alloc4", alloc.allocationKey, "wrong alloc")
+       assert.Check(t, !alloc1.IsPreempted(), "alloc1 not preempted")
+       assert.Check(t, alloc2.IsPreempted(), "alloc2 not preempted")
+       assert.Check(t, alloc3.IsPreempted(), "alloc3 preempted")
+}
+
+// 
TestTryPreemption_OnNode_AskResTypesDifferent_GuaranteedSetOnVictimAndPreemptorSides
 Test try preemption with 2 level queue hierarchy. Since Node doesn't have 
enough resources to accomodate, preemption happens because of node resource 
constraint.
+// Guaranteed set on both victim queue path and preemptor queue path.
+// Ask (Preemptor) resource type matches with one of the victim's resource 
types.  Still, needs to be preempted because matching resource type has been 
configured as guaranteed.
+// Setup:
+// Nodes are Node1. Node doesn't have space. Not able to accommodate the ask.
+// root.parent.parent1.child1. Guaranteed set on parent1, vcores: 2. Ask of 
vcores: 1 is waiting for resources.
+// root.parent.parent2.child2. Guaranteed set on parent2, vcores: 1. 6 
Allocations (belongs to two diff apps) are running. 3 Allocation's usage is 
vcores:1, mem: 100. 3 more allocations usage is mem: 100. Total usage is 
vcores:3, mem: 600
+// root.parent.parent2.child3. No usage, no guaranteed set
+// 2 Allocations of each vcores:1, mem: 100 running on 
root.parent.parent1.child2 should be preempted to free up resources for ask 
arrived in root.parent.parent1.child1.
+// 3rd allocation of vcores:1, mem: 100 should not be touched as preempting 
the same would make usage goes below the guaranteed set on 
root.parent.parent2.child2.
+// All remaining three allocation of each mem: 100 should not be touched at 
all as there is no matching resource type between these allocs and ask resource 
types.
+func 
TestTryPreemption_OnNode_AskResTypesDifferent_GuaranteedSetOnVictimAndPreemptorSides(t
 *testing.T) {
+       t.SkipNow()
+       node := newNode(node1, map[string]resources.Quantity{"vcores": 3, 
"mem": 600})
+       iterator := getNodeIteratorFn(node)
+       rootQ, err := createRootQueue(nil)
+       assert.NilError(t, err)
+       parentQ, err := createManagedQueueGuaranteed(rootQ, "parent", true, 
map[string]string{"vcores": "3"}, nil)
+       assert.NilError(t, err)
+       parentQ1, err := createManagedQueueGuaranteed(parentQ, "parent1", true, 
nil, nil)
+       assert.NilError(t, err)
+       parentQ2, err := createManagedQueueGuaranteed(parentQ, "parent2", true, 
nil, nil)
+       assert.NilError(t, err)
+
+       childQ1, err := createManagedQueueGuaranteed(parentQ1, "child1", false, 
nil, map[string]string{"vcores": "2"})
+       assert.NilError(t, err)
+       childQ2, err := createManagedQueueGuaranteed(parentQ2, "child2", false, 
nil, map[string]string{"vcores": "1"})
+       assert.NilError(t, err)
+       _, err = createManagedQueueGuaranteed(parentQ2, "child3", false, nil, 
nil)
+       assert.NilError(t, err)
+
+       app1 := newApplication(appID1, "default", "root.parent.parent2.child2")
+       app1.SetQueue(childQ2)
+       childQ2.applications[appID1] = app1
+       app2 := newApplication(appID2, "default", "root.parent.parent2.child2")
+       app2.SetQueue(childQ2)
+       childQ2.applications[appID2] = app2
+       app3 := newApplication(appID3, "default", "root.parent.parent2.child2")
+       app3.SetQueue(childQ2)
+       childQ2.applications[appID3] = app3
+
+       for i := 5; i < 8; i++ {
+               askN := newAllocationAsk(alloc+strconv.Itoa(i), appID1, 
resources.NewResourceFromMap(map[string]resources.Quantity{"mem": 100}))
+               askN.createTime = time.Now().Add(-2 * time.Minute)
+               assert.NilError(t, app1.AddAllocationAsk(askN))
+               allocN := NewAllocation(node1, askN)
+               app1.AddAllocation(allocN)
+               assert.Check(t, node.AddAllocation(allocN), "node alloc1 
failed")
+       }
+
+       ask1 := newAllocationAsk("alloc1", appID1, 
resources.NewResourceFromMap(map[string]resources.Quantity{"vcores": 1, "mem": 
100}))
+       ask1.createTime = time.Now().Add(-1 * time.Minute)
+       assert.NilError(t, app1.AddAllocationAsk(ask1))
+       ask2 := newAllocationAsk("alloc2", appID2, 
resources.NewResourceFromMap(map[string]resources.Quantity{"vcores": 1, "mem": 
100}))
+       ask2.createTime = time.Now()
+       assert.NilError(t, app1.AddAllocationAsk(ask2))
+       ask3 := newAllocationAsk("alloc3", appID2, 
resources.NewResourceFromMap(map[string]resources.Quantity{"vcores": 1, "mem": 
100}))
+       ask3.createTime = time.Now()
+       assert.NilError(t, app1.AddAllocationAsk(ask3))
+       alloc1 := NewAllocation(node1, ask1)
+       app1.AddAllocation(alloc1)
+       assert.Check(t, node.AddAllocation(alloc1), "node alloc1 failed")
+       alloc2 := NewAllocation(node1, ask2)
+       app2.AddAllocation(alloc2)
+       assert.Check(t, node.AddAllocation(alloc2), "node alloc2 failed")
+       alloc3 := NewAllocation(node1, ask3)
+       app3.AddAllocation(alloc3)
+       assert.Check(t, node.AddAllocation(alloc3), "node alloc3 failed")
+
+       for i := 5; i < 8; i++ {
+               assert.NilError(t, 
childQ2.IncAllocatedResource(resources.NewResourceFromMap(map[string]resources.Quantity{"mem":
 100}), false))
+       }
+       assert.NilError(t, 
childQ2.IncAllocatedResource(ask1.GetAllocatedResource(), false))
+       assert.NilError(t, 
childQ2.IncAllocatedResource(ask2.GetAllocatedResource(), false))
+       assert.NilError(t, 
childQ2.IncAllocatedResource(ask3.GetAllocatedResource(), false))
+
+       app4 := newApplication("app-4", "default", "root.parent.parent1.child1")
+       app4.SetQueue(childQ1)
+       ask4 := newAllocationAsk("alloc4", "app-4", 
resources.NewResourceFromMap(map[string]resources.Quantity{"vcores": 2}))
+       assert.NilError(t, app4.AddAllocationAsk(ask4))
+       headRoom := 
resources.NewResourceFromMap(map[string]resources.Quantity{"vcores": 2})
+       preemptor := NewPreemptor(app4, headRoom, 30*time.Second, ask4, 
iterator(), false)
+
+       // register predicate handler
+       preemptions := []mock.Preemption{mock.NewPreemption(true, "alloc4", 
node1, []string{"alloc3", "alloc2"}, 1, 1)}
+       plugin := mock.NewPreemptionPredicatePlugin(nil, nil, preemptions)
+       plugins.RegisterSchedulerPlugin(plugin)
+       defer plugins.UnregisterSchedulerPlugins()
+
+       alloc, ok := preemptor.TryPreemption()
+       assert.NilError(t, plugin.GetPredicateError())
+       assert.Assert(t, ok, "no victims found")
+       assert.Equal(t, "alloc4", alloc.allocationKey, "wrong alloc")
+       assert.Check(t, !alloc1.IsPreempted(), "alloc1 not preempted")
+       assert.Check(t, alloc2.IsPreempted(), "alloc2 not preempted")
+       assert.Check(t, alloc3.IsPreempted(), "alloc3 preempted")
+}
+
+// TestTryPreemption_AskResTypesSame_GuaranteedSetOnPreemptorSide Test try 
preemption with 2 level queue hierarchy.  Since Node doesn't have enough 
resources to accomodate, preemption happens because of node resource constraint.
+// Guaranteed set only on preemptor queue path.
+// Ask (Preemptor) resource type matches with one of the victim's resource 
types.  Still, needs to be preempted because matching resource type has been 
configured as guaranteed.
+// Setup:
+// Nodes are Node1. Node has enough space to accommodate the new ask.
+// root.parent.parent1.child1. Guaranteed set on parent1, vcores: 2. Ask of 
vcores: 2, mem: 200 is waiting for resources.
+// root.parent.parent2.child2. Guaranteed set on parent2, vcores: 1. 6 
Allocations (belongs to two diff apps) are running. 3 Allocation's usage is 
vcores:1. 3 more allocations usage gpu: 100. Total usage is vcores:3, gpu: 300
+// root.parent.parent2.child3. No usage, no guaranteed set
+// 3 Allocations of each vcores:1 running on root.parent.parent1.child2 could 
be preempted to free up resources for ask arrived in root.parent.parent1.child1.
+// but last allocation should not be touched as preempting the same would make 
usage goes above the guaranteed set on preemptor or ask queue 
root.parent.parent2.child1.
+// All remaining three allocation of each mem: 100 should not be touched at 
all as there is no matching resource type between these allocs and ask resource 
types.
+func TestTryPreemption_AskResTypesSame_GuaranteedSetOnPreemptorSide(t 
*testing.T) {
+       t.SkipNow()
+       node := newNode(node1, map[string]resources.Quantity{"vcores": 5, 
"gpu": 300, "mem": 200})
+       iterator := getNodeIteratorFn(node)
+       rootQ, err := createRootQueue(nil)
+       assert.NilError(t, err)
+       parentQ, err := createManagedQueueGuaranteed(rootQ, "parent", true, 
nil, nil)
+       assert.NilError(t, err)
+       parentQ1, err := createManagedQueueGuaranteed(parentQ, "parent1", true, 
nil, nil)
+       assert.NilError(t, err)
+       parentQ2, err := createManagedQueueGuaranteed(parentQ, "parent2", true, 
nil, nil)
+       assert.NilError(t, err)
+
+       childQ1, err := createManagedQueueGuaranteed(parentQ1, "child1", false, 
nil, map[string]string{"vcores": "2"})
+       assert.NilError(t, err)
+       childQ2, err := createManagedQueueGuaranteed(parentQ2, "child2", false, 
nil, nil)
+       assert.NilError(t, err)
+       _, err = createManagedQueueGuaranteed(parentQ2, "child3", false, nil, 
nil)
+       assert.NilError(t, err)
+
+       app1 := newApplication(appID1, "default", "root.parent.parent2.child2")
+       app1.SetQueue(childQ2)
+       childQ2.applications[appID1] = app1
+       app2 := newApplication(appID2, "default", "root.parent.parent2.child2")
+       app2.SetQueue(childQ2)
+       childQ2.applications[appID2] = app2
+       app3 := newApplication(appID3, "default", "root.parent.parent2.child2")
+       app3.SetQueue(childQ2)
+       childQ2.applications[appID3] = app3
+
+       for i := 5; i < 8; i++ {
+               askN := newAllocationAsk(alloc+strconv.Itoa(i), appID1, 
resources.NewResourceFromMap(map[string]resources.Quantity{"gpu": 100}))
+               askN.createTime = time.Now().Add(-2 * time.Minute)
+               assert.NilError(t, app1.AddAllocationAsk(askN))
+               allocN := NewAllocation(node1, askN)
+               app1.AddAllocation(allocN)
+               assert.Check(t, node.AddAllocation(allocN), "node alloc1 
failed")
+       }
+
+       ask1 := newAllocationAsk("alloc1", appID1, 
resources.NewResourceFromMap(map[string]resources.Quantity{"vcores": 1}))
+       ask1.createTime = time.Now().Add(-1 * time.Minute)
+       assert.NilError(t, app1.AddAllocationAsk(ask1))
+       ask2 := newAllocationAsk("alloc2", appID2, 
resources.NewResourceFromMap(map[string]resources.Quantity{"vcores": 1}))
+       ask2.createTime = time.Now()
+       assert.NilError(t, app1.AddAllocationAsk(ask2))
+       ask3 := newAllocationAsk("alloc3", appID2, 
resources.NewResourceFromMap(map[string]resources.Quantity{"vcores": 1}))
+       ask3.createTime = time.Now()
+       assert.NilError(t, app1.AddAllocationAsk(ask3))
+       alloc1 := NewAllocation(node1, ask1)
+       app1.AddAllocation(alloc1)
+       assert.Check(t, node.AddAllocation(alloc1), "node alloc1 failed")
+       alloc2 := NewAllocation(node1, ask2)
+       app2.AddAllocation(alloc2)
+       assert.Check(t, node.AddAllocation(alloc2), "node alloc2 failed")
+       alloc3 := NewAllocation(node1, ask3)
+       app3.AddAllocation(alloc3)
+       assert.Check(t, node.AddAllocation(alloc3), "node alloc3 failed")
+
+       for i := 5; i < 8; i++ {
+               assert.NilError(t, 
childQ2.IncAllocatedResource(resources.NewResourceFromMap(map[string]resources.Quantity{"gpu":
 100}), false))
+       }
+       assert.NilError(t, 
childQ2.IncAllocatedResource(ask1.GetAllocatedResource(), false))
+       assert.NilError(t, 
childQ2.IncAllocatedResource(ask2.GetAllocatedResource(), false))
+       assert.NilError(t, 
childQ2.IncAllocatedResource(ask3.GetAllocatedResource(), false))
+
+       app4 := newApplication("app-4", "default", "root.parent.parent1.child1")
+       app4.SetQueue(childQ1)
+       ask4 := newAllocationAsk("alloc4", "app-4", 
resources.NewResourceFromMap(map[string]resources.Quantity{"vcores": 2, "mem": 
200}))
+       assert.NilError(t, app4.AddAllocationAsk(ask4))
+       headRoom := 
resources.NewResourceFromMap(map[string]resources.Quantity{"vcores": 2})
+       preemptor := NewPreemptor(app4, headRoom, 30*time.Second, ask4, 
iterator(), false)
+
+       // register predicate handler
+       preemptions := []mock.Preemption{mock.NewPreemption(true, "alloc4", 
node1, []string{"alloc3", "alloc2"}, 1, 1)}
+       allocs := map[string]string{}
+       allocs["alloc4"] = node1
+       plugin := mock.NewPreemptionPredicatePlugin(nil, allocs, preemptions)
+       plugins.RegisterSchedulerPlugin(plugin)
+       defer plugins.UnregisterSchedulerPlugins()
+
+       alloc, ok := preemptor.TryPreemption()
+       assert.NilError(t, plugin.GetPredicateError())
+       assert.Assert(t, ok, "no victims found")
+       assert.Equal(t, "alloc4", alloc.allocationKey, "wrong alloc")
+       assert.Check(t, !alloc1.IsPreempted(), "alloc1 not preempted")
+       assert.Check(t, alloc2.IsPreempted(), "alloc2 not preempted")
+       assert.Check(t, alloc3.IsPreempted(), "alloc3 preempted")
+}
+
+// TestTryPreemption_OnNode_AskResTypesSame_GuaranteedSetOnPreemptorSide Test 
try preemption with 2 level queue hierarchy. Since Node doesn't have enough 
resources to accomodate, preemption happens because of node resource constraint.
+// Guaranteed set only on preemptor queue path.
+// Ask (Preemptor) resource type matches with one of the victim's resource 
types.  Still, needs to be preempted because matching resource type has been 
configured as guaranteed.
+// Setup:
+// Nodes are Node1. Node is full. Doesn't have space to accomodate the ask.
+// root.parent.parent1.child1. Guaranteed set on parent1, vcores: 2. Ask of 
vcores: 2, mem: 200 is waiting for resources.
+// root.parent.parent2.child2. Guaranteed set on parent2, vcores: 1. 6 
Allocations (belongs to two diff apps) are running. 3 Allocation's usage is 
vcores:1. 3 more allocations usage gpu: 100. Total usage is vcores:3, gpu: 300
+// root.parent.parent2.child3. No usage, no guaranteed set
+// 3 Allocations of each vcores:1 running on root.parent.parent1.child2 could 
be preempted to free up resources for ask arrived in root.parent.parent1.child1.
+// but last allocation should not be touched as preempting the same would make 
usage goes above the guaranteed set on preemptor or ask queue 
root.parent.parent2.child1.
+// All remaining three allocation of each mem: 100 should not be touched at 
all as there is no matching resource type between these allocs and ask resource 
types.
+func TestTryPreemption_OnNode_AskResTypesSame_GuaranteedSetOnPreemptorSide(t 
*testing.T) {
+       t.SkipNow()
+       node := newNode(node1, map[string]resources.Quantity{"vcores": 3, 
"gpu": 300, "mem": 200})
+       iterator := getNodeIteratorFn(node)
+       rootQ, err := createRootQueue(nil)
+       assert.NilError(t, err)
+       parentQ, err := createManagedQueueGuaranteed(rootQ, "parent", true, 
nil, nil)
+       assert.NilError(t, err)
+       parentQ1, err := createManagedQueueGuaranteed(parentQ, "parent1", true, 
nil, nil)
+       assert.NilError(t, err)
+       parentQ2, err := createManagedQueueGuaranteed(parentQ, "parent2", true, 
nil, nil)
+       assert.NilError(t, err)
+
+       childQ1, err := createManagedQueueGuaranteed(parentQ1, "child1", false, 
nil, map[string]string{"vcores": "2"})
+       assert.NilError(t, err)
+       childQ2, err := createManagedQueueGuaranteed(parentQ2, "child2", false, 
nil, nil)
+       assert.NilError(t, err)
+       _, err = createManagedQueueGuaranteed(parentQ2, "child3", false, nil, 
nil)
+       assert.NilError(t, err)
+
+       app1 := newApplication(appID1, "default", "root.parent.parent2.child2")
+       app1.SetQueue(childQ2)
+       childQ2.applications[appID1] = app1
+       app2 := newApplication(appID2, "default", "root.parent.parent2.child2")
+       app2.SetQueue(childQ2)
+       childQ2.applications[appID2] = app2
+       app3 := newApplication(appID3, "default", "root.parent.parent2.child2")
+       app3.SetQueue(childQ2)
+       childQ2.applications[appID3] = app3
+
+       for i := 5; i < 8; i++ {
+               askN := newAllocationAsk(alloc+strconv.Itoa(i), appID1, 
resources.NewResourceFromMap(map[string]resources.Quantity{"gpu": 100}))
+               askN.createTime = time.Now().Add(-2 * time.Minute)
+               assert.NilError(t, app1.AddAllocationAsk(askN))
+               allocN := NewAllocation(node1, askN)
+               app1.AddAllocation(allocN)
+               assert.Check(t, node.AddAllocation(allocN), "node alloc1 
failed")
+       }
+
+       ask1 := newAllocationAsk("alloc1", appID1, 
resources.NewResourceFromMap(map[string]resources.Quantity{"vcores": 1}))
+       ask1.createTime = time.Now().Add(-1 * time.Minute)
+       assert.NilError(t, app1.AddAllocationAsk(ask1))
+       ask2 := newAllocationAsk("alloc2", appID2, 
resources.NewResourceFromMap(map[string]resources.Quantity{"vcores": 1}))
+       ask2.createTime = time.Now()
+       assert.NilError(t, app1.AddAllocationAsk(ask2))
+       ask3 := newAllocationAsk("alloc3", appID2, 
resources.NewResourceFromMap(map[string]resources.Quantity{"vcores": 1}))
+       ask3.createTime = time.Now()
+       assert.NilError(t, app1.AddAllocationAsk(ask3))
+       alloc1 := NewAllocation(node1, ask1)
+       app1.AddAllocation(alloc1)
+       assert.Check(t, node.AddAllocation(alloc1), "node alloc1 failed")
+       alloc2 := NewAllocation(node1, ask2)
+       app2.AddAllocation(alloc2)
+       assert.Check(t, node.AddAllocation(alloc2), "node alloc2 failed")
+       alloc3 := NewAllocation(node1, ask3)
+       app3.AddAllocation(alloc3)
+       assert.Check(t, node.AddAllocation(alloc3), "node alloc3 failed")
+
+       for i := 5; i < 8; i++ {
+               assert.NilError(t, 
childQ2.IncAllocatedResource(resources.NewResourceFromMap(map[string]resources.Quantity{"gpu":
 100}), false))
+       }
+       assert.NilError(t, 
childQ2.IncAllocatedResource(ask1.GetAllocatedResource(), false))
+       assert.NilError(t, 
childQ2.IncAllocatedResource(ask2.GetAllocatedResource(), false))
+       assert.NilError(t, 
childQ2.IncAllocatedResource(ask3.GetAllocatedResource(), false))
+
+       app4 := newApplication("app-4", "default", "root.parent.parent1.child1")
+       app4.SetQueue(childQ1)
+       ask4 := newAllocationAsk("alloc4", "app-4", 
resources.NewResourceFromMap(map[string]resources.Quantity{"vcores": 2, "mem": 
200}))
+       assert.NilError(t, app4.AddAllocationAsk(ask4))
+       headRoom := 
resources.NewResourceFromMap(map[string]resources.Quantity{"vcores": 2})
+       preemptor := NewPreemptor(app4, headRoom, 30*time.Second, ask4, 
iterator(), false)
+
+       // register predicate handler
+       preemptions := []mock.Preemption{mock.NewPreemption(true, "alloc4", 
node1, []string{"alloc3", "alloc2"}, 1, 1)}
+       plugin := mock.NewPreemptionPredicatePlugin(nil, nil, preemptions)
+       plugins.RegisterSchedulerPlugin(plugin)
+       defer plugins.UnregisterSchedulerPlugins()
+
+       alloc, ok := preemptor.TryPreemption()
+       assert.NilError(t, plugin.GetPredicateError())
+       assert.Assert(t, ok, "no victims found")
+       assert.Equal(t, "alloc4", alloc.allocationKey, "wrong alloc")
+       assert.Check(t, !alloc1.IsPreempted(), "alloc1 not preempted")
+       assert.Check(t, alloc2.IsPreempted(), "alloc2 not preempted")
+       assert.Check(t, alloc3.IsPreempted(), "alloc3 preempted")
+}
+
+// TestTryPreemption_AskResTypesSame_GuaranteedSetOnVictimAndPreemptorSides 
Test try preemption with 2 level queue hierarchy.
+// Guaranteed set on both victim queue path and preemptor queue path.
+// Ask (Preemptor) resource type matches with one of the victim's resource 
types.  Still, needs to be preempted because matching resource type has been 
configured as guaranteed.
+// Setup:
+// Nodes are Node1. Node has enough space to accommodate the new ask.
+// root.parent.parent1.child1. Guaranteed set on parent1, vcores: 2. Ask of 
vcores: 2, mem: 200 is waiting for resources.
+// root.parent.parent2.child2. Guaranteed set on parent2, vcores: 1. 6 
Allocations (belongs to two diff apps) are running. 3 Allocation's usage is 
vcores:1. 3 more allocations usage gpu: 100. Total usage is vcores:3, gpu: 300
+// root.parent.parent2.child3. No usage, no guaranteed set
+// 2 Allocations of each vcores:1 running on root.parent.parent1.child2 could 
be preempted to free up resources for ask arrived in root.parent.parent1.child1.
+// 3rd allocation of vcores:1 should not be touched as preempting the same 
would make usage goes below the guaranteed set on root.parent.parent2.child2.
+// All remaining three allocation of each mem: 100 should not be touched at 
all as there is no matching resource type between these allocs and ask resource 
types.
+func 
TestTryPreemption_AskResTypesSame_GuaranteedSetOnVictimAndPreemptorSides(t 
*testing.T) {
+       t.SkipNow()
+       node := newNode(node1, map[string]resources.Quantity{"vcores": 5, 
"gpu": 700, "mem": 200})
+       iterator := getNodeIteratorFn(node)
+       rootQ, err := createRootQueue(nil)
+       assert.NilError(t, err)
+       parentQ, err := createManagedQueueGuaranteed(rootQ, "parent", true, 
nil, nil)
+       assert.NilError(t, err)
+       parentQ1, err := createManagedQueueGuaranteed(parentQ, "parent1", true, 
nil, nil)
+       assert.NilError(t, err)
+       parentQ2, err := createManagedQueueGuaranteed(parentQ, "parent2", true, 
nil, nil)
+       assert.NilError(t, err)
+
+       childQ1, err := createManagedQueueGuaranteed(parentQ1, "child1", false, 
nil, map[string]string{"vcores": "2"})
+       assert.NilError(t, err)
+       childQ2, err := createManagedQueueGuaranteed(parentQ2, "child2", false, 
nil, map[string]string{"vcores": "1"})
+       assert.NilError(t, err)
+       _, err = createManagedQueueGuaranteed(parentQ2, "child3", false, nil, 
nil)
+       assert.NilError(t, err)
+
+       app1 := newApplication(appID1, "default", "root.parent.parent2.child2")
+       app1.SetQueue(childQ2)
+       childQ2.applications[appID1] = app1
+       app2 := newApplication(appID2, "default", "root.parent.parent2.child2")
+       app2.SetQueue(childQ2)
+       childQ2.applications[appID2] = app2
+       app3 := newApplication(appID3, "default", "root.parent.parent2.child2")
+       app3.SetQueue(childQ2)
+       childQ2.applications[appID3] = app3
+
+       for i := 5; i < 8; i++ {
+               askN := newAllocationAsk(alloc+strconv.Itoa(i), appID1, 
resources.NewResourceFromMap(map[string]resources.Quantity{"gpu": 100}))
+               askN.createTime = time.Now().Add(-2 * time.Minute)
+               assert.NilError(t, app1.AddAllocationAsk(askN))
+               allocN := NewAllocation(node1, askN)
+               app1.AddAllocation(allocN)
+               assert.Check(t, node.AddAllocation(allocN), "node alloc1 
failed")
+       }
+
+       ask1 := newAllocationAsk("alloc1", appID1, 
resources.NewResourceFromMap(map[string]resources.Quantity{"vcores": 1}))
+       ask1.createTime = time.Now().Add(-1 * time.Minute)
+       assert.NilError(t, app1.AddAllocationAsk(ask1))
+       ask2 := newAllocationAsk("alloc2", appID2, 
resources.NewResourceFromMap(map[string]resources.Quantity{"vcores": 1}))
+       ask2.createTime = time.Now()
+       assert.NilError(t, app1.AddAllocationAsk(ask2))
+       ask3 := newAllocationAsk("alloc3", appID2, 
resources.NewResourceFromMap(map[string]resources.Quantity{"vcores": 1}))
+       ask3.createTime = time.Now()
+       assert.NilError(t, app1.AddAllocationAsk(ask3))
+       alloc1 := NewAllocation(node1, ask1)
+       app1.AddAllocation(alloc1)
+       assert.Check(t, node.AddAllocation(alloc1), "node alloc1 failed")
+       alloc2 := NewAllocation(node1, ask2)
+       app2.AddAllocation(alloc2)
+       assert.Check(t, node.AddAllocation(alloc2), "node alloc2 failed")
+       alloc3 := NewAllocation(node1, ask3)
+       app3.AddAllocation(alloc3)
+       assert.Check(t, node.AddAllocation(alloc3), "node alloc3 failed")
+
+       for i := 5; i < 8; i++ {
+               assert.NilError(t, 
childQ2.IncAllocatedResource(resources.NewResourceFromMap(map[string]resources.Quantity{"gpu":
 100}), false))
+       }
+
+       assert.NilError(t, 
childQ2.IncAllocatedResource(ask1.GetAllocatedResource(), false))
+       assert.NilError(t, 
childQ2.IncAllocatedResource(ask2.GetAllocatedResource(), false))
+       assert.NilError(t, 
childQ2.IncAllocatedResource(ask3.GetAllocatedResource(), false))
+
+       app4 := newApplication("app-4", "default", "root.parent.parent1.child1")
+       app4.SetQueue(childQ1)
+       ask4 := newAllocationAsk("alloc4", "app-4", 
resources.NewResourceFromMap(map[string]resources.Quantity{"vcores": 2, "mem": 
200}))
+       assert.NilError(t, app4.AddAllocationAsk(ask4))
+       headRoom := 
resources.NewResourceFromMap(map[string]resources.Quantity{"vcores": 2})
+       preemptor := NewPreemptor(app4, headRoom, 30*time.Second, ask4, 
iterator(), false)
+
+       // register predicate handler
+       preemptions := []mock.Preemption{mock.NewPreemption(true, "alloc4", 
node1, []string{"alloc3", "alloc2"}, 1, 1)}
+       allocs := map[string]string{}
+       allocs["alloc4"] = node1
+       plugin := mock.NewPreemptionPredicatePlugin(nil, allocs, preemptions)
+       plugins.RegisterSchedulerPlugin(plugin)
+       defer plugins.UnregisterSchedulerPlugins()
+
+       alloc, ok := preemptor.TryPreemption()
+       assert.NilError(t, plugin.GetPredicateError())
+       assert.Assert(t, ok, "no victims found")
+       assert.Equal(t, "alloc4", alloc.allocationKey, "wrong alloc")
+       assert.Check(t, !alloc1.IsPreempted(), "alloc1 not preempted")
+       assert.Check(t, alloc2.IsPreempted(), "alloc2 not preempted")
+       assert.Check(t, alloc3.IsPreempted(), "alloc3 preempted")
+}
+
+// 
TestTryPreemption_OnNode_AskResTypesSame_GuaranteedSetOnVictimAndPreemptorSides 
Test try preemption with 2 level queue hierarchy. Since Node doesn't have 
enough resources to accomodate, preemption happens because of node resource 
constraint.
+// Guaranteed set on both victim queue path and preemptor queue path.
+// Ask (Preemptor) resource type matches with one of the victim's resource 
types.  Still, needs to be preempted because matching resource type has been 
configured as guaranteed.
+// Setup:
+// Nodes are Node1. Node is full. Doesn't have enough space to accomodate the 
ask.
+// root.parent.parent1.child1. Guaranteed set on parent1, vcores: 2. Ask of 
vcores: 2, mem: 200 is waiting for resources.
+// root.parent.parent2.child2. Guaranteed set on parent2, vcores: 1. 6 
Allocations (belongs to two diff apps) are running. 3 Allocation's usage is 
vcores:1. 3 more allocations usage gpu: 100. Total usage is vcores:3, gpu: 300
+// root.parent.parent2.child3. No usage, no guaranteed set
+// 2 Allocations of each vcores:1 running on root.parent.parent1.child2 could 
be preempted to free up resources for ask arrived in root.parent.parent1.child1.
+// 3rd allocation of vcores:1 should not be touched as preempting the same 
would make usage goes below the guaranteed set on root.parent.parent2.child2.
+// All remaining three allocation of each mem: 100 should not be touched at 
all as there is no matching resource type between these allocs and ask resource 
types.
+func 
TestTryPreemption_OnNode_AskResTypesSame_GuaranteedSetOnVictimAndPreemptorSides(t
 *testing.T) {
+       t.SkipNow()
+       node := newNode(node1, map[string]resources.Quantity{"vcores": 3, 
"gpu": 700, "mem": 200})
+       iterator := getNodeIteratorFn(node)
+       rootQ, err := createRootQueue(nil)
+       assert.NilError(t, err)
+       parentQ, err := createManagedQueueGuaranteed(rootQ, "parent", true, 
nil, nil)
+       assert.NilError(t, err)
+       parentQ1, err := createManagedQueueGuaranteed(parentQ, "parent1", true, 
nil, nil)
+       assert.NilError(t, err)
+       parentQ2, err := createManagedQueueGuaranteed(parentQ, "parent2", true, 
nil, nil)
+       assert.NilError(t, err)
+
+       childQ1, err := createManagedQueueGuaranteed(parentQ1, "child1", false, 
nil, map[string]string{"vcores": "2"})
+       assert.NilError(t, err)
+       childQ2, err := createManagedQueueGuaranteed(parentQ2, "child2", false, 
nil, map[string]string{"vcores": "1"})
+       assert.NilError(t, err)
+       _, err = createManagedQueueGuaranteed(parentQ2, "child3", false, nil, 
nil)
+       assert.NilError(t, err)
+
+       app1 := newApplication(appID1, "default", "root.parent.parent2.child2")
+       app1.SetQueue(childQ2)
+       childQ2.applications[appID1] = app1
+       app2 := newApplication(appID2, "default", "root.parent.parent2.child2")
+       app2.SetQueue(childQ2)
+       childQ2.applications[appID2] = app2
+       app3 := newApplication(appID3, "default", "root.parent.parent2.child2")
+       app3.SetQueue(childQ2)
+       childQ2.applications[appID3] = app3
+
+       for i := 5; i < 8; i++ {
+               askN := newAllocationAsk(alloc+strconv.Itoa(i), appID1, 
resources.NewResourceFromMap(map[string]resources.Quantity{"gpu": 100}))
+               askN.createTime = time.Now().Add(-2 * time.Minute)
+               assert.NilError(t, app1.AddAllocationAsk(askN))
+               allocN := NewAllocation(node1, askN)
+               app1.AddAllocation(allocN)
+               assert.Check(t, node.AddAllocation(allocN), "node alloc1 
failed")
+       }
+
+       ask1 := newAllocationAsk("alloc1", appID1, 
resources.NewResourceFromMap(map[string]resources.Quantity{"vcores": 1}))
+       ask1.createTime = time.Now().Add(-1 * time.Minute)
+       assert.NilError(t, app1.AddAllocationAsk(ask1))
+       ask2 := newAllocationAsk("alloc2", appID2, 
resources.NewResourceFromMap(map[string]resources.Quantity{"vcores": 1}))
+       ask2.createTime = time.Now()
+       assert.NilError(t, app1.AddAllocationAsk(ask2))
+       ask3 := newAllocationAsk("alloc3", appID2, 
resources.NewResourceFromMap(map[string]resources.Quantity{"vcores": 1}))
+       ask3.createTime = time.Now()
+       assert.NilError(t, app1.AddAllocationAsk(ask3))
+       alloc1 := NewAllocation(node1, ask1)
+       app1.AddAllocation(alloc1)
+       assert.Check(t, node.AddAllocation(alloc1), "node alloc1 failed")
+       alloc2 := NewAllocation(node1, ask2)
+       app2.AddAllocation(alloc2)
+       assert.Check(t, node.AddAllocation(alloc2), "node alloc2 failed")
+       alloc3 := NewAllocation(node1, ask3)
+       app3.AddAllocation(alloc3)
+       assert.Check(t, node.AddAllocation(alloc3), "node alloc3 failed")
+
+       for i := 5; i < 8; i++ {
+               assert.NilError(t, 
childQ2.IncAllocatedResource(resources.NewResourceFromMap(map[string]resources.Quantity{"gpu":
 100}), false))
+       }
+
+       assert.NilError(t, 
childQ2.IncAllocatedResource(ask1.GetAllocatedResource(), false))
+       assert.NilError(t, 
childQ2.IncAllocatedResource(ask2.GetAllocatedResource(), false))
+       assert.NilError(t, 
childQ2.IncAllocatedResource(ask3.GetAllocatedResource(), false))
+
+       app4 := newApplication("app-4", "default", "root.parent.parent1.child1")
+       app4.SetQueue(childQ1)
+       ask4 := newAllocationAsk("alloc4", "app-4", 
resources.NewResourceFromMap(map[string]resources.Quantity{"vcores": 2, "mem": 
200}))
+       assert.NilError(t, app4.AddAllocationAsk(ask4))
+       headRoom := 
resources.NewResourceFromMap(map[string]resources.Quantity{"vcores": 2})
+       preemptor := NewPreemptor(app4, headRoom, 30*time.Second, ask4, 
iterator(), false)
+
+       // register predicate handler
+       preemptions := []mock.Preemption{mock.NewPreemption(true, "alloc4", 
node1, []string{"alloc3", "alloc2"}, 1, 1)}
+       plugin := mock.NewPreemptionPredicatePlugin(nil, nil, preemptions)
+       plugins.RegisterSchedulerPlugin(plugin)
+       defer plugins.UnregisterSchedulerPlugins()
+
+       alloc, ok := preemptor.TryPreemption()
+       assert.NilError(t, plugin.GetPredicateError())
+       assert.Assert(t, ok, "no victims found")
+       assert.Equal(t, "alloc4", alloc.allocationKey, "wrong alloc")
+       assert.Check(t, !alloc1.IsPreempted(), "alloc1 not preempted")
+       assert.Check(t, alloc2.IsPreempted(), "alloc2 not preempted")
+       assert.Check(t, alloc3.IsPreempted(), "alloc3 preempted")
+}
+
 func TestSolutionScoring(t *testing.T) {
        singleAlloc := scoreMap(nodeID1, []bool{false}, []bool{true})
        singleOriginator := scoreMap(nodeID1, []bool{true}, []bool{true})


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to