This is an automated email from the ASF dual-hosted git repository.
ccondit pushed a commit to branch branch-1.6
in repository https://gitbox.apache.org/repos/asf/yunikorn-core.git
The following commit(s) were added to refs/heads/branch-1.6 by this push:
new 6ea2765b [YUNIKORN-2926] Placeholder counters incorrect (#986)
6ea2765b is described below
commit 6ea2765b3dade7d1946e8ece486c041f02b6a353
Author: Wilfred Spiegelenburg <[email protected]>
AuthorDate: Thu Oct 24 11:54:05 2024 -0500
[YUNIKORN-2926] Placeholder counters incorrect (#986)
Placeholder tracking data is maintained inside the application for
scheduling. If the placeholder is released we update the counters in the
tracking data. We have cases in which we do not do that correctly:
* placeholders are smaller than the real allocation
* placeholder does not have an allocation to replace
* all allocations are removed from an application
Closes: #986
Signed-off-by: Craig Condit <[email protected]>
---
pkg/scheduler/objects/application.go | 58 +++++----
pkg/scheduler/objects/application_test.go | 208 ++++++++++++++++--------------
pkg/scheduler/partition_test.go | 72 +++++++----
3 files changed, 193 insertions(+), 145 deletions(-)
diff --git a/pkg/scheduler/objects/application.go
b/pkg/scheduler/objects/application.go
index a6840854..0fe682aa 100644
--- a/pkg/scheduler/objects/application.go
+++ b/pkg/scheduler/objects/application.go
@@ -409,7 +409,7 @@ func (sa *Application) clearPlaceholderTimer() {
}
// timeoutPlaceholderProcessing cleans up all placeholder asks and allocations
that are not used after the timeout.
-// If the application has started processing, Starting state or further, the
application keeps on processing without
+// If the application has started processing, Running state or further, the
application keeps on processing without
// being able to use the placeholders.
// If the application is in New or Accepted state we clean up and take
followup action based on the gang scheduling
// style.
@@ -429,17 +429,14 @@ func (sa *Application) timeoutPlaceholderProcessing() {
}
alloc.SetReleased(true)
toRelease = append(toRelease, alloc)
- // mark as timeout out in the tracking data
- if _, ok := sa.placeholderData[alloc.GetTaskGroup()];
ok {
-
sa.placeholderData[alloc.GetTaskGroup()].TimedOut++
- }
}
log.Log(log.SchedApplication).Info("Placeholder timeout,
releasing placeholders",
zap.String("AppID", sa.ApplicationID),
zap.Int("placeholders being replaced", replacing),
zap.Int("releasing placeholders", len(toRelease)))
+ // trigger the release of the placeholders: accounting updates
when the release is done
sa.notifyRMAllocationReleased(toRelease,
si.TerminationType_TIMEOUT, "releasing allocated placeholders on placeholder
timeout")
- // Case 2: in every other case fail the application, and notify the
context about the expired placeholder asks
+ // Case 2: in every other case progress the application, and notify the
context about the expired placeholder asks
default:
log.Log(log.SchedApplication).Info("Placeholder timeout,
releasing asks and placeholders",
zap.String("AppID", sa.ApplicationID),
@@ -1809,22 +1806,28 @@ func (sa *Application) updatePreemptedResource(info
*Allocation) {
info.GetAllocatedResource(), info.GetBindTime())
}
+// ReplaceAllocation removes the placeholder from the allocation list and
replaces it with the real allocation.
+// If no replacing allocation is linked to the placeholder it will still be
removed from the application.
+// Queue and Node objects are updated by the caller.
func (sa *Application) ReplaceAllocation(allocationKey string) *Allocation {
sa.Lock()
defer sa.Unlock()
// remove the placeholder that was just confirmed by the shim
ph := sa.removeAllocationInternal(allocationKey,
si.TerminationType_PLACEHOLDER_REPLACED)
- // this has already been replaced or it is a duplicate message from the
shim
- if ph == nil || !ph.HasRelease() {
- log.Log(log.SchedApplication).Debug("Unexpected placeholder
released",
+ // this has already been replaced, or it is a duplicate message from
the shim just ignore
+ if ph == nil {
+ return nil
+ }
+ // ph is the placeholder, the releases entry points to the real
allocation we need to swap in
+ alloc := ph.GetRelease()
+ if alloc == nil {
+ log.Log(log.SchedApplication).Warn("Placeholder replaced
without replacement allocation",
zap.String("applicationID", sa.ApplicationID),
zap.Stringer("placeholder", ph))
- return nil
+ return ph
}
// update the replacing allocation
// we double linked the real and placeholder allocation
- // ph is the placeholder, the releases entry points to the real one
- alloc := ph.GetRelease()
alloc.SetPlaceholderUsed(true)
alloc.SetPlaceholderCreateTime(ph.GetCreateTime())
alloc.SetBindTime(time.Now())
@@ -1832,13 +1835,10 @@ func (sa *Application) ReplaceAllocation(allocationKey
string) *Allocation {
// order is important: clean up the allocation after adding it to the
app
// we need the original Replaced allocation resultType.
alloc.ClearRelease()
- if sa.placeholderData != nil {
- sa.placeholderData[ph.GetTaskGroup()].Replaced++
- }
return ph
}
-// Remove the Allocation from the application.
+// RemoveAllocation removes the Allocation from the application.
// Return the allocation that was removed or nil if not found.
func (sa *Application) RemoveAllocation(allocationKey string, releaseType
si.TerminationType) *Allocation {
sa.Lock()
@@ -1846,8 +1846,9 @@ func (sa *Application) RemoveAllocation(allocationKey
string, releaseType si.Ter
return sa.removeAllocationInternal(allocationKey, releaseType)
}
-// Remove the Allocation from the application
-// No locking must be called while holding the lock
+// removeAllocationInternal removes the Allocation from the application.
+// Returns the allocation that was removed or nil if not found.
+// No locking must be called while holding the application lock.
func (sa *Application) removeAllocationInternal(allocationKey string,
releaseType si.TerminationType) *Allocation {
alloc := sa.allocations[allocationKey]
@@ -1862,9 +1863,14 @@ func (sa *Application)
removeAllocationInternal(allocationKey string, releaseTyp
// update correct allocation tracker
if alloc.IsPlaceholder() {
// make sure we account for the placeholders being removed in
the tracking data
- if releaseType == si.TerminationType_STOPPED_BY_RM ||
releaseType == si.TerminationType_PREEMPTED_BY_SCHEDULER || releaseType ==
si.TerminationType_UNKNOWN_TERMINATION_TYPE {
- if _, ok := sa.placeholderData[alloc.taskGroupName]; ok
{
-
sa.placeholderData[alloc.taskGroupName].TimedOut++
+ // update based on termination type: everything is counted as a
timeout except for a real replace
+ if sa.placeholderData != nil {
+ if phData, ok :=
sa.placeholderData[alloc.taskGroupName]; ok {
+ if releaseType ==
si.TerminationType_PLACEHOLDER_REPLACED {
+ phData.Replaced++
+ } else {
+ phData.TimedOut++
+ }
}
}
// as and when every ph gets removed (for replacement),
resource usage would be reduced.
@@ -1937,7 +1943,7 @@ func (sa *Application) hasZeroAllocations() bool {
return resources.IsZero(sa.pending) &&
resources.IsZero(sa.allocatedResource)
}
-// Remove all allocations from the application.
+// RemoveAllAllocations removes all allocations from the application.
// All allocations that have been removed are returned.
func (sa *Application) RemoveAllAllocations() []*Allocation {
sa.Lock()
@@ -1945,6 +1951,12 @@ func (sa *Application) RemoveAllAllocations()
[]*Allocation {
allocationsToRelease := make([]*Allocation, 0)
for _, alloc := range sa.allocations {
+ // update placeholder tracking data
+ if alloc.IsPlaceholder() && sa.placeholderData != nil {
+ if phData, ok :=
sa.placeholderData[alloc.taskGroupName]; ok {
+ phData.TimedOut++
+ }
+ }
allocationsToRelease = append(allocationsToRelease, alloc)
// Aggregate the resources used by this alloc to the
application's user resource tracker
sa.trackCompletedResource(alloc)
@@ -1963,7 +1975,7 @@ func (sa *Application) RemoveAllAllocations()
[]*Allocation {
// When the resource trackers are zero we should not expect anything to
come in later.
if resources.IsZero(sa.pending) {
if err := sa.HandleApplicationEvent(CompleteApplication); err
!= nil {
- log.Log(log.SchedApplication).Warn("Application state
not changed to Waiting while removing all allocations",
+ log.Log(log.SchedApplication).Warn("Application state
not changed to Completing while removing all allocations",
zap.String("currentState", sa.CurrentState()),
zap.Error(err))
}
diff --git a/pkg/scheduler/objects/application_test.go
b/pkg/scheduler/objects/application_test.go
index 09712585..91db298f 100644
--- a/pkg/scheduler/objects/application_test.go
+++ b/pkg/scheduler/objects/application_test.go
@@ -525,42 +525,33 @@ func TestAddAllocAsk(t *testing.T) {
assert.Assert(t, app.IsAccepted(), "Application should have stayed in
accepted state")
// test PlaceholderData
- tg1 := "tg-1"
+ const (
+ tg1 = "tg-1"
+ tg2 = "tg-2"
+ )
ask = newAllocationAskTG(aKey, appID1, tg1, res)
err = app.AddAllocationAsk(ask)
assert.NilError(t, err, "ask should have been updated on app")
app.SetTimedOutPlaceholder(tg1, 1)
- app.SetTimedOutPlaceholder("tg-2", 2)
+ app.SetTimedOutPlaceholder(tg2, 2)
clonePlaceholderData := app.GetAllPlaceholderData()
assert.Equal(t, len(clonePlaceholderData), 1)
assert.Equal(t, len(app.placeholderData), 1)
assert.Equal(t, clonePlaceholderData[0], app.placeholderData[tg1])
- assert.Equal(t, app.placeholderData[tg1].TaskGroupName, tg1)
- assert.Equal(t, app.placeholderData[tg1].Count, int64(1))
- assert.Equal(t, app.placeholderData[tg1].Replaced, int64(0))
- assert.Equal(t, app.placeholderData[tg1].TimedOut, int64(1))
- assert.DeepEqual(t, app.placeholderData[tg1].MinResource, res)
+ assertPlaceholderData(t, app, tg1, 1, 1, 0, res)
ask = newAllocationAskTG(aKey, appID1, tg1, res)
err = app.AddAllocationAsk(ask)
assert.NilError(t, err, "ask should have been updated on app")
assert.Equal(t, len(app.placeholderData), 1)
- assert.Equal(t, app.placeholderData[tg1].TaskGroupName, tg1)
- assert.Equal(t, app.placeholderData[tg1].Count, int64(2))
- assert.Equal(t, app.placeholderData[tg1].Replaced, int64(0))
- assert.Equal(t, app.placeholderData[tg1].TimedOut, int64(1))
- assert.DeepEqual(t, app.placeholderData[tg1].MinResource, res)
+ assertPlaceholderData(t, app, tg1, 2, 1, 0, res)
- tg2 := "tg-2"
ask = newAllocationAskTG(aKey, appID1, tg2, res)
err = app.AddAllocationAsk(ask)
assert.NilError(t, err, "ask should have been updated on app")
+
assert.Equal(t, len(app.placeholderData), 2)
- assert.Equal(t, app.placeholderData[tg2].TaskGroupName, tg2)
- assert.Equal(t, app.placeholderData[tg2].Count, int64(1))
- assert.Equal(t, app.placeholderData[tg2].Replaced, int64(0))
- assert.Equal(t, app.placeholderData[tg2].TimedOut, int64(0))
- assert.DeepEqual(t, app.placeholderData[tg2].MinResource, res)
+ assertPlaceholderData(t, app, tg2, 1, 0, 0, res)
}
// test state change on add and remove ask
@@ -632,15 +623,7 @@ func TestRecoverAllocAsk(t *testing.T) {
assert.Equal(t, 0, len(app.placeholderData))
ask = newAllocationAskTG("ask-3", appID1, "testGroup", res)
app.RecoverAllocationAsk(ask)
- phData := app.placeholderData
- assert.Equal(t, 1, len(phData))
- taskGroupData := phData["testGroup"]
- assert.Assert(t, taskGroupData != nil)
- assert.Equal(t, "testGroup", taskGroupData.TaskGroupName)
- assert.Equal(t, int64(1), taskGroupData.Count)
- assert.Equal(t, int64(0), taskGroupData.Replaced)
- assert.Equal(t, int64(0), taskGroupData.TimedOut)
- assert.Assert(t, resources.Equals(taskGroupData.MinResource, res))
+ assertPlaceholderData(t, app, "testGroup", 1, 0, 0, res)
}
// test reservations removal by allocation
@@ -1232,13 +1215,24 @@ func assertResourceUsage(t *testing.T, appSummary
*ApplicationSummary, memorySec
}
}
-func assertPlaceHolderResource(t *testing.T, appSummary *ApplicationSummary,
memorySeconds int64,
- vcoresSecconds int64) {
+func assertPlaceHolderResource(t *testing.T, appSummary *ApplicationSummary,
memorySeconds int64, vcoresSecconds int64) {
detailedResource :=
appSummary.PlaceholderResource.TrackedResourceMap[instType1]
assert.Equal(t, memorySeconds,
int64(detailedResource.Resources["memory"]))
assert.Equal(t, vcoresSecconds,
int64(detailedResource.Resources["vcores"]))
}
+func assertPlaceholderData(t *testing.T, app *Application, taskGroup string,
count, timedout, replaced int, res *resources.Resource) {
+ assert.Assert(t, len(app.placeholderData) >= 1, "expected placeholder
data to be set")
+ phData, ok := app.placeholderData[taskGroup]
+ assert.Assert(t, ok, "placeholder data not for the taskgroup: %s",
taskGroup)
+ assert.Equal(t, phData.Count, int64(count), "placeholder count does not
match")
+ assert.Equal(t, phData.Replaced, int64(replaced), "replaced count does
not match")
+ assert.Equal(t, phData.TimedOut, int64(timedout), "timedout count does
not match")
+ if res != nil {
+ assert.Assert(t, resources.Equals(phData.MinResource, res),
"resource for taskgroup is not correct")
+ }
+}
+
func TestResourceUsageAggregation(t *testing.T) {
setupUGM()
@@ -1421,13 +1415,8 @@ func TestReplaceAllocation(t *testing.T) {
// add the placeholder to the app
app.AddAllocation(ph)
// add PlaceholderData
- app.addPlaceholderDataWithLocking(ph)
- assert.Equal(t, len(app.placeholderData), 1)
- assert.Equal(t, app.placeholderData["tg"].TaskGroupName, "tg")
- assert.Equal(t, app.placeholderData["tg"].Count, int64(1))
- assert.Equal(t, app.placeholderData["tg"].Replaced, int64(0))
- assert.Equal(t, app.placeholderData["tg"].TimedOut, int64(0))
- assert.DeepEqual(t, app.placeholderData["tg"].MinResource, res)
+ app.addPlaceholderData(ph)
+ assertPlaceholderData(t, app, "tg", 1, 0, 0, res)
assert.Equal(t, len(app.allocations), 1, "allocation not added as
expected")
assert.Assert(t, resources.IsZero(app.allocatedResource), "placeholder
counted as real allocation")
@@ -1435,15 +1424,20 @@ func TestReplaceAllocation(t *testing.T) {
t.Fatalf("placeholder allocation not updated as expected: got
%s, expected %s", app.allocatedPlaceholder, res)
}
assertUserGroupResource(t, getTestUserGroup(), res)
+ // if the placeholder exists it should be removed even without real
allocation linked
alloc = app.ReplaceAllocation(ph.GetAllocationKey())
- assert.Equal(t, alloc, nilAlloc, "placeholder without releases expected
nil to be returned got a real alloc: %s", alloc)
- assert.Equal(t, app.placeholderData["tg"].Replaced, int64(0))
+ assert.Equal(t, alloc, ph, "returned allocation is not the placeholder")
+ // placeholder data must show replaced increase
+ assertPlaceholderData(t, app, "tg", 1, 0, 1, res)
assertUserGroupResource(t, getTestUserGroup(), nil)
+ assert.Assert(t, resources.IsZero(app.allocatedPlaceholder),
"placeholder should have been released")
+ assert.Assert(t, resources.IsZero(app.allocatedResource), "no
replacement made allocated should be zero")
+
// add the placeholder back to the app, the failure test above changed
state and removed the ph
app.SetState(Running.String())
app.AddAllocation(ph)
- app.addPlaceholderDataWithLocking(ph)
- assert.Equal(t, app.placeholderData["tg"].Count, int64(2))
+ app.addPlaceholderData(ph)
+ assertPlaceholderData(t, app, "tg", 2, 0, 1, res)
assertUserGroupResource(t, getTestUserGroup(), res)
// set the real one to replace the placeholder
@@ -1452,10 +1446,8 @@ func TestReplaceAllocation(t *testing.T) {
alloc = app.ReplaceAllocation(ph.GetAllocationKey())
assert.Equal(t, alloc, ph, "returned allocation is not the placeholder")
assert.Assert(t, resources.IsZero(app.allocatedPlaceholder), "real
allocation counted as placeholder")
- if !resources.Equals(app.allocatedResource, res) {
- t.Fatalf("real allocation not updated as expected: got %s,
expected %s", app.allocatedResource, res)
- }
- assert.Equal(t, app.placeholderData["tg"].Replaced, int64(1))
+ assert.Assert(t, resources.Equals(app.allocatedResource, res), "real
allocation not updated as expected")
+ assertPlaceholderData(t, app, "tg", 2, 0, 2, res)
assert.Equal(t, realAlloc.GetPlaceholderCreateTime(),
ph.GetCreateTime(), "real allocation's placeholder create time not updated as
expected: got %s, expected %s", realAlloc.GetPlaceholderCreateTime(),
ph.GetCreateTime())
assertUserGroupResource(t, getTestUserGroup(), res)
@@ -1463,8 +1455,8 @@ func TestReplaceAllocation(t *testing.T) {
app.SetState(Running.String())
ph.ClearRelease()
app.AddAllocation(ph)
- app.addPlaceholderDataWithLocking(ph)
- assert.Equal(t, app.placeholderData["tg"].Count, int64(3))
+ app.addPlaceholderData(ph)
+ assertPlaceholderData(t, app, "tg", 3, 0, 2, res)
assertUserGroupResource(t, getTestUserGroup(), resources.Multiply(res,
2))
}
@@ -1485,14 +1477,14 @@ func TestReplaceAllocationTracking(t *testing.T) {
ph3.SetInstanceType(instType1)
app.AddAllocation(ph1)
assert.NilError(t, err, "could not add ask")
- app.addPlaceholderDataWithLocking(ph1)
+ app.addPlaceholderData(ph1)
assert.Equal(t, true, app.HasPlaceholderAllocation())
app.AddAllocation(ph2)
assert.NilError(t, err, "could not add ask")
- app.addPlaceholderDataWithLocking(ph2)
+ app.addPlaceholderData(ph2)
app.AddAllocation(ph3)
assert.NilError(t, err, "could not add ask")
- app.addPlaceholderDataWithLocking(ph3)
+ app.addPlaceholderData(ph3)
ph1.SetBindTime(time.Now().Add(-10 * time.Second))
ph2.SetBindTime(time.Now().Add(-10 * time.Second))
@@ -1523,15 +1515,20 @@ func TestReplaceAllocationTracking(t *testing.T) {
assertPlaceHolderResource(t, appSummary, 3000, 300)
}
-func TestTimeoutPlaceholderSoftStyle(t *testing.T) {
+func TestTimeoutPlaceholderSoft(t *testing.T) {
runTimeoutPlaceholderTest(t, Resuming.String(), Soft, []int{1, 2})
}
-func TestTimeoutPlaceholderAllocAsk(t *testing.T) {
+func TestTimeoutPlaceholderHard(t *testing.T) {
runTimeoutPlaceholderTest(t, Failing.String(), Hard, []int{1, 2})
}
func runTimeoutPlaceholderTest(t *testing.T, expectedState string,
gangSchedulingStyle string, expectedReleases []int) {
+ const (
+ tg1 = "tg-1"
+ tg2 = "tg-2"
+ )
+
setupUGM()
// create a fake queue
queue, err := createRootQueue(nil)
@@ -1551,36 +1548,35 @@ func runTimeoutPlaceholderTest(t *testing.T,
expectedState string, gangSchedulin
res, err := resources.NewResourceFromConf(resMap)
assert.NilError(t, err, "Unexpected error when creating resource from
map")
// add the placeholder ask to the app
- tg1 := "tg-1"
phAsk := newAllocationAskTG("ask-1", appID1, tg1, res)
err = app.AddAllocationAsk(phAsk)
assert.NilError(t, err, "Application ask should have been added")
+ assertPlaceholderData(t, app, tg1, 1, 0, 0, res)
assert.Assert(t, app.IsAccepted(), "Application should be in accepted
state")
- // check PlaceHolderData
- assert.Equal(t, len(app.placeholderData), 1)
- assert.Equal(t, app.placeholderData[tg1].TaskGroupName, tg1)
- assert.Equal(t, app.placeholderData[tg1].Count, int64(1))
- assert.Equal(t, app.placeholderData[tg1].Replaced, int64(0))
- assert.Equal(t, app.placeholderData[tg1].TimedOut, int64(0))
- assert.DeepEqual(t, app.placeholderData[tg1].MinResource, res)
-
// add the placeholder to the app
- ph := newPlaceholderAlloc(appID1, nodeID1, res, "tg")
+ ph := newPlaceholderAlloc(appID1, nodeID1, res, tg2)
app.AddAllocation(ph)
+ app.addPlaceholderDataWithLocking(ph)
+ assertPlaceholderData(t, app, tg2, 1, 0, 0, res)
assertUserGroupResource(t, getTestUserGroup(), res)
assert.Assert(t, app.getPlaceholderTimer() != nil, "Placeholder timer
should be initiated after the first placeholder allocation")
// add a second one to check the filter
- ph = newPlaceholderAlloc(appID1, nodeID1, res, "tg")
+ ph = newPlaceholderAlloc(appID1, nodeID1, res, tg2)
app.AddAllocation(ph)
+ app.addPlaceholderDataWithLocking(ph)
+ assertPlaceholderData(t, app, tg2, 2, 0, 0, res)
assertUserGroupResource(t, getTestUserGroup(), resources.Multiply(res,
2))
+ assert.Assert(t, app.IsAccepted(), "Application should be in accepted
state")
err = common.WaitForCondition(10*time.Millisecond, 1*time.Second,
func() bool {
app.RLock()
defer app.RUnlock()
return app.placeholderTimer == nil
})
- assert.Equal(t, app.placeholderData[tg1].TimedOut,
app.placeholderData[tg1].Count, "When the app is in an accepted state, timeout
should equal to count")
assert.NilError(t, err, "Placeholder timeout cleanup did not trigger
unexpectedly")
+ // When the app was in the accepted state, timeout should equal to count
+ assertPlaceholderData(t, app, tg1, 1, 1, 0, res)
+ assertPlaceholderData(t, app, tg2, 2, 2, 0, res)
assert.Equal(t, app.stateMachine.Current(), expectedState, "Application
did not progress into expected state")
assertUserGroupResource(t, getTestUserGroup(), resources.Multiply(res,
2))
events := testHandler.GetEvents()
@@ -1593,12 +1589,8 @@ func runTimeoutPlaceholderTest(t *testing.T,
expectedState string, gangSchedulin
idx++
}
}
- // check if the Replaced of PlaceHolderData is 0
- assert.Equal(t, app.placeholderData[tg1].Replaced, int64(0))
- // Because the Count of PlaceHolderData is only added in
AddAllocationAsk, so it is 1
- assert.Equal(t, app.placeholderData[tg1].Count, int64(1))
-
assert.Equal(t, found, 2, "release allocation or ask event not found in
list")
+
// asks are completely cleaned up
assert.Assert(t, resources.IsZero(app.GetPendingResource()), "pending
placeholder resources should be zero")
// a released placeholder still holds the resource until release
confirmed by the RM
@@ -1612,6 +1604,8 @@ func runTimeoutPlaceholderTest(t *testing.T,
expectedState string, gangSchedulin
}
func TestTimeoutPlaceholderAllocReleased(t *testing.T) {
+ const tg1 = "tg-1"
+
setupUGM()
originalPhTimeout := defaultPlaceholderTimeout
@@ -1626,24 +1620,18 @@ func TestTimeoutPlaceholderAllocReleased(t *testing.T) {
res, err := resources.NewResourceFromConf(resMap)
assert.NilError(t, err, "Unexpected error when creating resource from
map")
// add the placeholders to the app: one released, one still available.
- ph := newPlaceholderAlloc(appID1, nodeID1, res, "tg")
- ph.SetReleased(true)
- app.AddAllocation(ph)
- // add PlaceholderData
- app.addPlaceholderDataWithLocking(ph)
- assert.Equal(t, len(app.placeholderData), 1)
- assert.Equal(t, app.placeholderData["tg"].TaskGroupName, "tg")
- assert.Equal(t, app.placeholderData["tg"].Count, int64(1))
- assert.Equal(t, app.placeholderData["tg"].Replaced, int64(0))
- assert.Equal(t, app.placeholderData["tg"].TimedOut, int64(0))
- assert.DeepEqual(t, app.placeholderData["tg"].MinResource, res)
+ phReleased := newPlaceholderAlloc(appID1, nodeID1, res, tg1)
+ phReleased.SetReleased(true)
+ app.AddAllocation(phReleased)
+ app.addPlaceholderDataWithLocking(phReleased)
+ assertPlaceholderData(t, app, tg1, 1, 0, 0, res)
assertUserGroupResource(t, getTestUserGroup(), resources.Multiply(res,
1))
assert.Assert(t, app.getPlaceholderTimer() != nil, "Placeholder timer
should be initiated after the first placeholder allocation")
- ph = newPlaceholderAlloc(appID1, nodeID1, res, "tg")
+ ph := newPlaceholderAlloc(appID1, nodeID1, res, tg1)
app.AddAllocation(ph)
app.addPlaceholderDataWithLocking(ph)
- assert.Equal(t, app.placeholderData["tg"].Count, int64(2))
+ assertPlaceholderData(t, app, tg1, 2, 0, 0, res)
assertUserGroupResource(t, getTestUserGroup(), resources.Multiply(res,
2))
alloc := newAllocation(appID1, nodeID1, res)
@@ -1669,9 +1657,24 @@ func TestTimeoutPlaceholderAllocReleased(t *testing.T) {
assert.Assert(t, resources.Equals(app.GetAllocatedResource(), res),
"Unexpected allocated resources for the app")
// a released placeholder still holds the resource until release
confirmed by the RM
assert.Assert(t, resources.Equals(app.GetPlaceholderResource(),
resources.Multiply(res, 2)), "Unexpected placeholder resources for the app")
- assert.Equal(t, app.placeholderData["tg"].Replaced, int64(0))
- assert.Equal(t, app.placeholderData["tg"].TimedOut, int64(1))
+ // tracking data not updated until confirmed by the RM
+ assertPlaceholderData(t, app, tg1, 2, 0, 0, res)
assertUserGroupResource(t, getTestUserGroup(), resources.Multiply(res,
3))
+ // do what the RM does and respond to the release
+ removed := app.RemoveAllocation(ph.allocationKey,
si.TerminationType_TIMEOUT)
+ assert.Assert(t, removed != nil, "expected allocation got nil")
+ assert.Equal(t, ph.allocationKey, removed.allocationKey, "expected
placeholder to be returned")
+ assertPlaceholderData(t, app, tg1, 2, 1, 0, res)
+ assert.Assert(t, resources.Equals(app.GetPlaceholderResource(), res),
"placeholder resources still accounted for on the app")
+ assertUserGroupResource(t, getTestUserGroup(), resources.Multiply(res,
2))
+
+ // process the replacement no real alloc linked account for that
+ removed = app.ReplaceAllocation(phReleased.allocationKey)
+ assert.Assert(t, removed != nil, "expected allocation got nil")
+ assert.Equal(t, phReleased.allocationKey, removed.allocationKey,
"expected placeholder to be returned")
+ assertPlaceholderData(t, app, tg1, 2, 1, 1, res)
+ assert.Assert(t, resources.IsZero(app.GetPlaceholderResource()),
"placeholder resources still accounted for on the app")
+ assertUserGroupResource(t, getTestUserGroup(), res)
}
func TestTimeoutPlaceholderCompleting(t *testing.T) {
@@ -1686,9 +1689,12 @@ func TestTimeoutPlaceholderCompleting(t *testing.T) {
res, err := resources.NewResourceFromConf(resMap)
assert.NilError(t, err, "Unexpected error when creating resource from
map")
// add the placeholder to the app
- ph := newPlaceholderAlloc(appID1, nodeID1, res, "tg")
+ tg := "tg-1"
+ ph := newPlaceholderAlloc(appID1, nodeID1, res, tg)
app.AddAllocation(ph)
assert.Assert(t, app.getPlaceholderTimer() != nil, "Placeholder timer
should be initiated after the first placeholder allocation")
+ app.addPlaceholderDataWithLocking(ph)
+ assertPlaceholderData(t, app, tg, 1, 0, 0, res)
assertUserGroupResource(t, getTestUserGroup(), resources.Multiply(res,
1))
// add a real allocation as well
alloc := newAllocation(appID1, nodeID1, res)
@@ -1714,8 +1720,15 @@ func TestTimeoutPlaceholderCompleting(t *testing.T) {
}
}
assert.Assert(t, found, "release allocation event not found in list")
- assert.Assert(t, app.IsCompleting(), "App should still be in completing
state")
+ assert.Assert(t, app.IsCompleting(), "App should be in completing
state")
assertUserGroupResource(t, getTestUserGroup(), resources.Multiply(res,
1))
+ // tracking data not updated until confirmed by the RM
+ assertPlaceholderData(t, app, tg, 1, 0, 0, res)
+ // do what the RM does and respond to the release
+ removed := app.RemoveAllocation(ph.allocationKey,
si.TerminationType_TIMEOUT)
+ assert.Assert(t, removed != nil, "expected allocation got nil")
+ assert.Equal(t, ph.allocationKey, removed.allocationKey, "expected
placeholder to be returned")
+ assertPlaceholderData(t, app, tg, 1, 1, 0, res)
}
func TestAppTimersAfterAppRemoval(t *testing.T) {
@@ -1730,9 +1743,12 @@ func TestAppTimersAfterAppRemoval(t *testing.T) {
res, err := resources.NewResourceFromConf(resMap)
assert.NilError(t, err, "Unexpected error when creating resource from
map")
// add the placeholder to the app
- ph := newPlaceholderAlloc(appID1, nodeID1, res, "tg")
+ tg := "tg-1"
+ ph := newPlaceholderAlloc(appID1, nodeID1, res, tg)
app.AddAllocation(ph)
assert.Assert(t, app.getPlaceholderTimer() != nil, "Placeholder timer
should be initiated after the first placeholder allocation")
+ app.addPlaceholderDataWithLocking(ph)
+ assertPlaceholderData(t, app, tg, 1, 0, 0, res)
assertUserGroupResource(t, getTestUserGroup(), resources.Multiply(res,
1))
// add a real allocation as well
alloc := newAllocation(appID1, nodeID1, res)
@@ -1749,6 +1765,7 @@ func TestAppTimersAfterAppRemoval(t *testing.T) {
if app.stateTimer != nil {
t.Fatalf("State timer has not be cleared after app removal as
expected, %v", app.stateTimer)
}
+ assertPlaceholderData(t, app, tg, 1, 1, 0, res)
}
func TestIncAndDecUserResourceUsage(t *testing.T) {
@@ -1867,12 +1884,17 @@ func TestFinishedTime(t *testing.T) {
}
func TestCanReplace(t *testing.T) {
+ const (
+ tg1 = "available"
+ tg2 = "unavailable"
+ tg3 = "timedout"
+ )
+
app := newApplication(appID1, "default", "root.unknown")
resMap := map[string]string{"memory": "100", "vcores": "10"}
res, err := resources.NewResourceFromConf(resMap)
assert.NilError(t, err, "Unexpected error when creating resource from
map")
- tg1 := "available"
tests := []struct {
name string
ask *Allocation
@@ -1890,14 +1912,12 @@ func TestCanReplace(t *testing.T) {
}
// add the placeholder data
// available tg has one replacement open
- app.addPlaceholderDataWithLocking(newAllocationAskTG(aKey, appID1, tg1,
res))
+ app.addPlaceholderData(newAllocationAskTG(aKey, appID1, tg1, res))
// unavailable tg has NO replacement open (replaced)
- tg2 := "unavailable"
- app.addPlaceholderDataWithLocking(newAllocationAskTG(aKey, appID1, tg2,
res))
+ app.addPlaceholderData(newAllocationAskTG(aKey, appID1, tg2, res))
app.placeholderData[tg2].Replaced++
// unavailable tg has NO replacement open (timedout)
- tg3 := "timedout"
- app.addPlaceholderDataWithLocking(newAllocationAskTG(aKey, appID1, tg3,
res))
+ app.addPlaceholderData(newAllocationAskTG(aKey, appID1, tg3, res))
app.placeholderData[tg3].TimedOut++
tests = []struct {
name string
@@ -2737,8 +2757,8 @@ func TestGetOutstandingRequests_AskReplaceable(t
*testing.T) {
sr.insert(allocationAsk2)
sr.insert(allocationAsk3)
app.sortedRequests = sr
- app.addPlaceholderDataWithLocking(allocationAsk1)
- app.addPlaceholderDataWithLocking(allocationAsk2)
+ app.addPlaceholderData(allocationAsk1)
+ app.addPlaceholderData(allocationAsk2)
var total []*Allocation
headroom :=
resources.NewResourceFromMap(map[string]resources.Quantity{"memory": 10})
diff --git a/pkg/scheduler/partition_test.go b/pkg/scheduler/partition_test.go
index b47fb234..79c4cdd5 100644
--- a/pkg/scheduler/partition_test.go
+++ b/pkg/scheduler/partition_test.go
@@ -451,7 +451,7 @@ func TestPlaceholderDataWithPlaceholderPreemption(t
*testing.T) {
assert.Equal(t, 7, partition.GetTotalAllocationCount(), "placeholder
allocation should be counted as normal allocations on the partition")
assert.Equal(t, 6, partition.getPhAllocationCount(), "placeholder
allocations should be counted as placeholders on the partition")
- assertPlaceholderData(t, gangApp, 6, 0)
+ assertPlaceholderData(t, gangApp, 6, 0, 0)
partition.removeApplication(appID1)
assert.Equal(t, 6, partition.GetTotalAllocationCount(), "remove app did
not remove allocation from count")
assert.Equal(t, 6, partition.getPhAllocationCount(), "placeholder
allocations changed unexpectedly")
@@ -505,7 +505,7 @@ func TestPlaceholderDataWithPlaceholderPreemption(t
*testing.T) {
assert.Assert(t, confirmed == nil, "not expecting any confirmed
allocations")
assert.Equal(t, 5, partition.GetTotalAllocationCount(), "preempted
placeholder should be removed from allocations")
assert.Equal(t, 5, partition.getPhAllocationCount(), "preempted
placeholder should be removed")
- assertPlaceholderData(t, gangApp, 6, 1)
+ assertPlaceholderData(t, gangApp, 6, 1, 0)
}
// test node removal effect on placeholder data
@@ -584,11 +584,11 @@ func TestPlaceholderDataWithNodeRemoval(t *testing.T) {
// try to allocate a last placeholder via normal allocate
partition.tryAllocate()
- assertPlaceholderData(t, gangApp, 7, 0)
+ assertPlaceholderData(t, gangApp, 7, 0, 0)
// Remove node
partition.removeNode(nodeID2)
- assertPlaceholderData(t, gangApp, 7, 4)
+ assertPlaceholderData(t, gangApp, 7, 4, 0)
}
// Test removal of placeholder has been accounted as timed out in app
placeholder data
@@ -669,7 +669,7 @@ func TestPlaceholderDataWithRemoval(t *testing.T) {
// try to allocate a last placeholder via normal allocate
partition.tryAllocate()
- assertPlaceholderData(t, gangApp, 7, 0)
+ assertPlaceholderData(t, gangApp, 7, 0, 0)
// release allocation: do what the context would do after the shim
processing
release := &si.AllocationRelease{
@@ -680,16 +680,17 @@ func TestPlaceholderDataWithRemoval(t *testing.T) {
}
releases, _ := partition.removeAllocation(release)
assert.Equal(t, 1, len(releases), "unexpected number of allocations
released")
- assertPlaceholderData(t, gangApp, 7, 1)
+ assertPlaceholderData(t, gangApp, 7, 1, 0)
}
// check PlaceHolderData
-func assertPlaceholderData(t *testing.T, gangApp *objects.Application, count
int64, timedout int64) {
+func assertPlaceholderData(t *testing.T, gangApp *objects.Application, count,
timedout, replaced int64) {
assert.Equal(t, len(gangApp.GetAllPlaceholderData()), 1)
- assert.Equal(t, gangApp.GetAllPlaceholderData()[0].TaskGroupName,
taskGroup)
- assert.Equal(t, gangApp.GetAllPlaceholderData()[0].Count, count)
- assert.Equal(t, gangApp.GetAllPlaceholderData()[0].Replaced, int64(0))
- assert.Equal(t, gangApp.GetAllPlaceholderData()[0].TimedOut, timedout)
+ phData := gangApp.GetAllPlaceholderData()[0]
+ assert.Equal(t, phData.TaskGroupName, taskGroup)
+ assert.Equal(t, phData.Count, count, "placeholder count does not match")
+ assert.Equal(t, phData.Replaced, replaced, "replaced count does not
match")
+ assert.Equal(t, phData.TimedOut, timedout, "timedout count does not
match")
}
// test with a replacement of a placeholder: placeholder on the removed node,
real on the 2nd node
@@ -2941,6 +2942,8 @@ func TestPlaceholderSmallerThanReal(t *testing.T) {
ask := newAllocationAskTG(phID, appID1, taskGroup, phRes, true)
err = app.AddAllocationAsk(ask)
assert.NilError(t, err, "failed to add placeholder ask ph-1 to app")
+ assertPlaceholderData(t, app, 1, 0, 0)
+
// try to allocate a placeholder via normal allocate
result := partition.tryAllocate()
if result == nil || result.Request == nil {
@@ -2974,6 +2977,7 @@ func TestPlaceholderSmallerThanReal(t *testing.T) {
released, _ := partition.removeAllocation(release)
assert.Equal(t, 0, partition.getPhAllocationCount(), "ph should not be
registered")
+ assertPlaceholderData(t, app, 1, 1, 0)
assert.Equal(t, 0, len(released), "expected no releases")
assert.Assert(t, resources.IsZero(node.GetAllocatedResource()),
"nothing should be allocated on node")
@@ -3000,7 +3004,7 @@ func TestPlaceholderSmallerMulti(t *testing.T) {
app := newApplicationTG(appID1, "default", "root.default", tgRes)
err = partition.AddApplication(app)
assert.NilError(t, err, "app-1 should have been added to the partition")
- phs := make(map[string]*objects.Allocation, 5)
+ phs := make(map[string]*objects.Allocation, phCount)
for i := 0; i < phCount; i++ {
// add an ask for a placeholder and allocate
id := "ph-" + strconv.Itoa(i)
@@ -3015,6 +3019,8 @@ func TestPlaceholderSmallerMulti(t *testing.T) {
assert.Equal(t, id, result.Request.GetAllocationKey(),
"expected allocation of %s to be returned", id)
phs[id] = result.Request
}
+ assertPlaceholderData(t, app, int64(phCount), 0, 0)
+
assert.Assert(t, resources.Equals(tgRes,
app.GetQueue().GetAllocatedResource()), "all placeholders should be allocated
on queue")
assert.Assert(t, resources.Equals(tgRes, node.GetAllocatedResource()),
"all placeholders should be allocated on node")
assert.Equal(t, phCount, partition.GetTotalAllocationCount(),
"placeholder allocation should be counted as normal allocations on the
partition")
@@ -3046,6 +3052,9 @@ func TestPlaceholderSmallerMulti(t *testing.T) {
released, _ := partition.removeAllocation(release)
assert.Equal(t, 0, len(released), "expected no releases")
}
+ // check the tracking details for the placeholders
+ assertPlaceholderData(t, app, int64(phCount), int64(phCount), 0)
+
assert.Assert(t, resources.IsZero(node.GetAllocatedResource()),
"nothing should be allocated on node")
assert.Assert(t,
resources.IsZero(app.GetQueue().GetAllocatedResource()), "nothing should be
allocated on queue")
assert.Equal(t, 0, partition.GetTotalAllocationCount(), "no allocation
should be registered on the partition")
@@ -3081,6 +3090,8 @@ func TestPlaceholderBiggerThanReal(t *testing.T) {
if result == nil || result.Request == nil {
t.Fatal("expected placeholder ph-1 to be allocated")
}
+ assertPlaceholderData(t, app, 1, 0, 0)
+
assert.Equal(t, phID, result.Request.GetAllocationKey(), "expected
allocation of ph-1 to be returned")
assert.Assert(t, resources.Equals(phRes,
app.GetQueue().GetAllocatedResource()), "placeholder size should be allocated
on queue")
assert.Assert(t, resources.Equals(phRes, node.GetAllocatedResource()),
"placeholder size should be allocated on node")
@@ -3116,6 +3127,8 @@ func TestPlaceholderBiggerThanReal(t *testing.T) {
if confirmed == nil {
t.Fatal("one allocation should be confirmed")
}
+ assertPlaceholderData(t, app, 1, 0, 1)
+
assert.Equal(t, 1, partition.GetTotalAllocationCount(), "real
allocation should be registered on the partition")
assert.Equal(t, 0, partition.getPhAllocationCount(), "no placeholder
allocation should be registered")
assert.Assert(t, resources.Equals(smallRes,
app.GetQueue().GetAllocatedResource()), "real size should be allocated on
queue")
@@ -3142,6 +3155,7 @@ func TestPlaceholderMatch(t *testing.T) {
ask := newAllocationAskTG(phID, appID1, taskGroup, phRes, true)
err = app.AddAllocationAsk(ask)
assert.NilError(t, err, "failed to add placeholder ask ph-1 to app")
+ assertPlaceholderData(t, app, 1, 0, 0)
// try to allocate a placeholder via normal allocate
result := partition.tryAllocate()
if result == nil || result.Request == nil {
@@ -3149,7 +3163,6 @@ func TestPlaceholderMatch(t *testing.T) {
}
phAllocationKey := result.Request.GetAllocationKey()
assert.Equal(t, phID, phAllocationKey, "expected allocation of ph-1 to
be returned")
- assert.Equal(t, 1, len(app.GetAllPlaceholderData()), "placeholder data
should be created on allocate")
assert.Equal(t, 1, partition.GetTotalAllocationCount(), "placeholder
allocation should be registered as allocation")
assert.Equal(t, 1, partition.getPhAllocationCount(), "placeholder
allocation should be registered")
assertLimits(t, getTestUserGroup(), phRes)
@@ -3165,9 +3178,7 @@ func TestPlaceholderMatch(t *testing.T) {
assert.Equal(t, 2, partition.GetTotalAllocationCount(), "allocations
should be registered: ph + normal")
assert.Equal(t, 1, partition.getPhAllocationCount(), "placeholder
allocation should be registered")
assert.Equal(t, allocKey, result.Request.GetAllocationKey(), "expected
allocation of alloc-1 to be returned")
- assert.Equal(t, 1, len(app.GetAllPlaceholderData()), "placeholder data
should not be updated")
- assert.Equal(t, int64(1), app.GetAllPlaceholderData()[0].Count,
"placeholder data should show 1 available placeholder")
- assert.Equal(t, int64(0), app.GetAllPlaceholderData()[0].Replaced,
"placeholder data should show no replacements")
+ assertPlaceholderData(t, app, 1, 0, 0)
assertLimits(t, getTestUserGroup(), resources.Multiply(phRes, 2))
// add a new ask the same task group as the placeholder
@@ -3178,9 +3189,7 @@ func TestPlaceholderMatch(t *testing.T) {
if result != nil {
t.Fatal("expected ask not to be allocated (matched task group)")
}
- assert.Equal(t, 1, len(app.GetAllPlaceholderData()), "placeholder data
should not be updated")
- assert.Equal(t, int64(1), app.GetAllPlaceholderData()[0].Count,
"placeholder data should show 1 available placeholder")
- assert.Equal(t, int64(0), app.GetAllPlaceholderData()[0].Replaced,
"placeholder data should show no replacements")
+ assertPlaceholderData(t, app, 1, 0, 0)
assertLimits(t, getTestUserGroup(), resources.Multiply(phRes, 2))
// replace the placeholder should work
@@ -3191,8 +3200,7 @@ func TestPlaceholderMatch(t *testing.T) {
assert.Equal(t, 2, partition.GetTotalAllocationCount(), "allocations
should be registered: ph + normal")
assert.Equal(t, 1, partition.getPhAllocationCount(), "placeholder
allocation should be registered")
assert.Equal(t, allocKey2, result.Request.GetAllocationKey(), "expected
allocation of alloc-2 to be returned")
- assert.Equal(t, int64(1), app.GetAllPlaceholderData()[0].Count,
"placeholder data should show 1 available placeholder")
- assert.Equal(t, int64(0), app.GetAllPlaceholderData()[0].Replaced,
"placeholder data should show no replacements yet")
+ assertPlaceholderData(t, app, 1, 0, 0)
// release placeholder: do what the context would do after the shim
processing
release := &si.AllocationRelease{
@@ -3206,9 +3214,9 @@ func TestPlaceholderMatch(t *testing.T) {
if confirmed == nil {
t.Fatal("confirmed allocation should not be nil")
}
+ assertPlaceholderData(t, app, 1, 0, 1)
assert.Equal(t, 2, partition.GetTotalAllocationCount(), "two
allocations should be registered")
assert.Equal(t, 0, partition.getPhAllocationCount(), "no placeholder
allocation should be registered")
- assert.Equal(t, int64(1), app.GetAllPlaceholderData()[0].Replaced,
"placeholder data should show the replacement")
assertLimits(t, getTestUserGroup(), resources.Multiply(phRes, 2))
// add a new ask the same task group as the placeholder
@@ -3223,6 +3231,7 @@ func TestPlaceholderMatch(t *testing.T) {
assertLimits(t, getTestUserGroup(), resources.Multiply(phRes, 3))
assert.Equal(t, 3, partition.GetTotalAllocationCount(), "three
allocations should be registered")
assert.Equal(t, 0, partition.getPhAllocationCount(), "no placeholder
allocation should be registered")
+ assertPlaceholderData(t, app, 1, 0, 1)
}
func TestPreemptedPlaceholderSkip(t *testing.T) {
@@ -3243,6 +3252,7 @@ func TestPreemptedPlaceholderSkip(t *testing.T) {
ask := newAllocationAskTG(phID, appID1, taskGroup, phRes, true)
err = app.AddAllocationAsk(ask)
assert.NilError(t, err, "failed to add placeholder ask ph-1 to app")
+ assertPlaceholderData(t, app, 1, 0, 0)
// try to allocate a placeholder via normal allocate
result := partition.tryAllocate()
if result == nil || result.Request == nil {
@@ -3251,7 +3261,6 @@ func TestPreemptedPlaceholderSkip(t *testing.T) {
ph := result.Request
phAllocationKey := result.Request.GetAllocationKey()
assert.Equal(t, phID, phAllocationKey, "expected allocation of ph-1 to
be returned")
- assert.Equal(t, 1, len(app.GetAllPlaceholderData()), "placeholder data
should be created on allocate")
assert.Equal(t, 1, partition.GetTotalAllocationCount(), "placeholder
allocation should be registered as allocation")
assert.Equal(t, 1, partition.getPhAllocationCount(), "placeholder
allocation should be registered")
@@ -3285,7 +3294,8 @@ func TestPreemptedPlaceholderSkip(t *testing.T) {
if confirmed != nil {
t.Fatal("confirmed allocation should be nil")
}
- assert.Equal(t, int64(1), app.GetAllPlaceholderData()[0].TimedOut,
"placeholder data should show the preemption")
+ // preemption shows as timedout
+ assertPlaceholderData(t, app, 1, 1, 0)
assert.Equal(t, 0, partition.GetTotalAllocationCount(), "no allocation
should be registered")
assert.Equal(t, 0, partition.getPhAllocationCount(), "no placeholder
allocation should be registered")
@@ -3295,10 +3305,8 @@ func TestPreemptedPlaceholderSkip(t *testing.T) {
t.Fatal("expected ask to be allocated (no placeholder left)")
}
assert.Equal(t, allocKey, result.Request.GetAllocationKey(), "expected
allocation of alloc-1 to be returned")
- assert.Equal(t, 1, len(app.GetAllPlaceholderData()), "placeholder data
should not be updated")
- assert.Equal(t, int64(1), app.GetAllPlaceholderData()[0].Count,
"placeholder data should show 1 available placeholder")
- assert.Equal(t, int64(0), app.GetAllPlaceholderData()[0].Replaced,
"placeholder data should show no replacements")
- assert.Equal(t, int64(1), app.GetAllPlaceholderData()[0].TimedOut,
"placeholder data should show the preemption")
+ // no change is the placeholder tracking
+ assertPlaceholderData(t, app, 1, 1, 0)
assert.Equal(t, 1, partition.GetTotalAllocationCount(), "allocation
should be registered as allocation")
assert.Equal(t, 0, partition.getPhAllocationCount(), "placeholder
allocation should be registered")
}
@@ -3331,6 +3339,8 @@ func TestTryPlaceholderAllocate(t *testing.T) {
ask := newAllocationAskTG(phID, appID1, taskGroup, res, true)
err = app.AddAllocationAsk(ask)
assert.NilError(t, err, "failed to add placeholder ask ph-1 to app")
+ assertPlaceholderData(t, app, 1, 0, 0)
+
// try to allocate placeholder should just return
result := partition.tryPlaceholderAllocate()
if result != nil {
@@ -3355,6 +3365,8 @@ func TestTryPlaceholderAllocate(t *testing.T) {
ask = newAllocationAskTG("ph-2", appID1, taskGroup, res, true)
err = app.AddAllocationAsk(ask)
assert.NilError(t, err, "failed to add placeholder ask ph-2 to app")
+ assertPlaceholderData(t, app, 2, 0, 0)
+
// try to allocate placeholder should just return
result = partition.tryPlaceholderAllocate()
if result != nil {
@@ -3423,6 +3435,8 @@ func TestTryPlaceholderAllocate(t *testing.T) {
if !resources.Equals(app.GetAllocatedResource(), res) {
t.Fatalf("allocations not updated as expected: got %s, expected
%s", app.GetAllocatedResource(), res)
}
+ assertPlaceholderData(t, app, 2, 0, 1)
+
assertLimits(t, getTestUserGroup(), resources.Multiply(res, 2))
}
@@ -3458,6 +3472,7 @@ func TestFailReplacePlaceholder(t *testing.T) {
ask := newAllocationAskTG(phID, appID1, taskGroup, res, true)
err = app.AddAllocationAsk(ask)
assert.NilError(t, err, "failed to add placeholder ask ph-1 to app")
+ assertPlaceholderData(t, app, 1, 0, 0)
// try to allocate a placeholder via normal allocate
result := partition.tryAllocate()
@@ -3519,6 +3534,7 @@ func TestFailReplacePlaceholder(t *testing.T) {
assert.Assert(t, resources.IsZero(node.GetAllocatedResource()), "node-1
allocated resources should be zero")
assert.Assert(t, resources.Equals(node2.GetAllocatedResource(), res),
"node-2 allocations not set as expected: got %s, expected %s",
node2.GetAllocatedResource(), res)
assert.Assert(t, !app.IsCompleting(), "application with allocation
should not be in COMPLETING state")
+ assertPlaceholderData(t, app, 1, 0, 1)
assertLimits(t, getTestUserGroup(), res)
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]