chenyulin0719 commented on code in PR #1004:
URL: https://github.com/apache/yunikorn-core/pull/1004#discussion_r1894631136


##########
pkg/scheduler/objects/application_test.go:
##########
@@ -3438,3 +3427,172 @@ func TestApplication_canAllocationReserve(t *testing.T) 
{
                })
        }
 }
+
+func TestTryPlaceHolderAllocateNoPlaceHolders(t *testing.T) {
+       node := newNode(nodeID1, map[string]resources.Quantity{"first": 5})
+       nodeMap := map[string]*Node{nodeID1: node}
+       iterator := getNodeIteratorFn(node)
+       getNode := func(nodeID string) *Node {
+               return nodeMap[nodeID]
+       }
+
+       app := newApplication(appID0, "default", "root.default")
+
+       queue, err := createRootQueue(nil)
+       assert.NilError(t, err, "queue create failed")
+       app.queue = queue
+
+       res := 
resources.NewResourceFromMap(map[string]resources.Quantity{"first": 5})
+       ask := newAllocationAsk(aKey, appID0, res)
+       ask.taskGroupName = tg1
+       err = app.AddAllocationAsk(ask)
+       assert.NilError(t, err, "ask should have been added to app")
+
+       result := app.tryPlaceholderAllocate(iterator, getNode)
+       assert.Assert(t, result == nil, "result should be nil since there are 
no placeholders to allocate")
+}
+
+func TestTryPlaceHolderAllocateSmallerRequest(t *testing.T) {
+       node := newNode(nodeID1, map[string]resources.Quantity{"first": 5})
+       nodeMap := map[string]*Node{nodeID1: node}
+       iterator := getNodeIteratorFn(node)
+       getNode := func(nodeID string) *Node {
+               return nodeMap[nodeID]
+       }
+
+       app := newApplication(appID0, "default", "root.default")
+
+       queue, err := createRootQueue(nil)
+       assert.NilError(t, err, "queue create failed")
+       app.queue = queue
+
+       res := 
resources.NewResourceFromMap(map[string]resources.Quantity{"first": 5})
+       ph := newPlaceholderAlloc(appID0, nodeID1, res, tg1)
+       app.AddAllocation(ph)
+       app.addPlaceholderData(ph)
+       assertPlaceholderData(t, app, tg1, 1, 0, 0, res)
+
+       // allocation request is smaller than placeholder
+       smallerRes := 
resources.NewResourceFromMap(map[string]resources.Quantity{"first": 1})
+       ask := newAllocationAsk(aKey, appID0, smallerRes)
+       ask.taskGroupName = tg1
+       err = app.AddAllocationAsk(ask)
+       assert.NilError(t, err, "ask should have been added to app")
+
+       result := app.tryPlaceholderAllocate(iterator, getNode)
+       assert.Assert(t, result != nil, "result should not be nil since the ask 
is smaller than the placeholder")
+       assert.Equal(t, Replaced, result.ResultType, "result type should be 
Replaced")
+       assert.Equal(t, nodeID1, result.NodeID, "result should be on the same 
node as placeholder")
+       assert.Equal(t, ask, result.Request, "result should contain the ask")
+       assert.Equal(t, ph, result.Request.GetRelease(), "real allocation 
should link to placeholder")
+       assert.Equal(t, result.Request, ph.GetRelease(), "placeholder should 
link to real allocation")
+       // placeholder data remains unchanged until RM confirms the replacement
+       assertPlaceholderData(t, app, tg1, 1, 0, 0, res)
+}
+
+func TestTryPlaceHolderAllocateLargerRequest(t *testing.T) {
+       node := newNode(nodeID1, map[string]resources.Quantity{"first": 5})
+       nodeMap := map[string]*Node{nodeID1: node}
+       iterator := getNodeIteratorFn(node)
+       getNode := func(nodeID string) *Node {
+               return nodeMap[nodeID]
+       }
+
+       app := newApplication(appID0, "default", "root.default")
+
+       queue, err := createRootQueue(nil)
+       assert.NilError(t, err, "queue create failed")
+       app.queue = queue
+
+       res := 
resources.NewResourceFromMap(map[string]resources.Quantity{"first": 5})
+       ph := newPlaceholderAlloc(appID0, nodeID1, res, tg1)
+       app.AddAllocation(ph)
+       app.addPlaceholderData(ph)
+       assertPlaceholderData(t, app, tg1, 1, 0, 0, res)
+
+       // allocation request is larger than placeholder
+       largerRes := 
resources.NewResourceFromMap(map[string]resources.Quantity{"first": 10})
+       ask := newAllocationAsk(aKey, appID0, largerRes)
+       ask.taskGroupName = tg1
+       err = app.AddAllocationAsk(ask)
+       assert.NilError(t, err, "ask should have been added to app")
+
+       result := app.tryPlaceholderAllocate(iterator, getNode)
+       assert.Assert(t, result == nil, "result should be nil since the ask is 
larger than the placeholder")
+       assert.Assert(t, ph.IsReleased(), "placeholder should have been 
released")
+       // placeholder data remains unchanged until RM confirms the release
+       assertPlaceholderData(t, app, tg1, 1, 0, 0, res)
+}
+
+func TestTryPlaceHolderAllocateDifferentTaskGroups(t *testing.T) {
+       node := newNode(nodeID1, map[string]resources.Quantity{"first": 5})
+       nodeMap := map[string]*Node{nodeID1: node}
+       iterator := getNodeIteratorFn(node)
+       getNode := func(nodeID string) *Node {
+               return nodeMap[nodeID]
+       }
+
+       app := newApplication(appID0, "default", "root.default")
+
+       queue, err := createRootQueue(nil)
+       assert.NilError(t, err, "queue create failed")
+       app.queue = queue
+
+       res := 
resources.NewResourceFromMap(map[string]resources.Quantity{"first": 5})
+       ph := newPlaceholderAlloc(appID0, nodeID1, res, tg1)
+       app.AddAllocation(ph)
+       app.addPlaceholderData(ph)
+       assertPlaceholderData(t, app, tg1, 1, 0, 0, res)
+
+       // allocation request has a different task group
+       ask := newAllocationAsk(aKey, appID0, res)
+       ask.taskGroupName = tg2
+       err = app.AddAllocationAsk(ask)
+       assert.NilError(t, err, "ask should have been added to app")
+
+       result := app.tryPlaceholderAllocate(iterator, getNode)
+       assert.Assert(t, result == nil, "result should be nil since the ask has 
a different task group")
+}
+
+func TestTryPlaceHolderAllocateDifferentNodes(t *testing.T) {
+       node1 := newNode(nodeID1, map[string]resources.Quantity{"first": 5})
+       node2 := newNode(nodeID2, map[string]resources.Quantity{"first": 5})
+       nodeMap := map[string]*Node{nodeID1: node1, nodeID2: node2}
+       iterator := getNodeIteratorFn(node1, node2)
+       getNode := func(nodeID string) *Node {
+               return nodeMap[nodeID]
+       }
+
+       app := newApplication(appID0, "default", "root.default")
+
+       queue, err := createRootQueue(nil)
+       assert.NilError(t, err, "queue create failed")
+       app.queue = queue
+
+       res := 
resources.NewResourceFromMap(map[string]resources.Quantity{"first": 5})
+       ph := newPlaceholderAlloc(appID0, nodeID1, res, tg1)
+       app.AddAllocation(ph)
+       app.addPlaceholderData(ph)
+       assertPlaceholderData(t, app, tg1, 1, 0, 0, res)
+
+       // predicate check fails on node1 and passes on node2
+       mockPlugin := mockCommon.NewPredicatePlugin(false, 
map[string]int{nodeID1: 0})

Review Comment:
   At the beginning, I'm confused about why using `{nodeID1: 0}) (fail always)` 
instead of `{nodeID1: -1}) (fail reserve)`.  After rethinking it, I realize 
it's reasonable because if we set `{nodeID1: -1})`, `nodeID1` will be picked 
again in the following `try all nodes` check , the 
[preAllocateCheck()](https://github.com/apache/yunikorn-core/blob/2113cd7e439c840330db313901d8f7855ab3b532/pkg/scheduler/objects/application.go#L1241C1-L1242C1)
 will pass.  
   
   So it make sense to me now.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to