You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@yunikorn.apache.org by cc...@apache.org on 2025/02/20 17:19:13 UTC

(yunikorn-core) branch master updated: [YUNIKORN-2153] Refactor placement of predicateCheckResult (#1011)

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

ccondit 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 84bb8e0c [YUNIKORN-2153] Refactor placement of predicateCheckResult (#1011)
84bb8e0c is described below

commit 84bb8e0c67248e559a193563d439d13006eb52fd
Author: kaichiachen <ka...@gmail.com>
AuthorDate: Thu Feb 20 11:18:52 2025 -0600

    [YUNIKORN-2153] Refactor placement of predicateCheckResult (#1011)
    
    Closes: #1011
    
    Signed-off-by: Craig Condit <cc...@apache.org>
---
 pkg/scheduler/objects/predicates.go      | 170 ++++++++++++++++++++
 pkg/scheduler/objects/predicates_test.go | 256 +++++++++++++++++++++++++++++++
 pkg/scheduler/objects/preemption.go      | 118 --------------
 pkg/scheduler/objects/preemption_test.go |  55 -------
 4 files changed, 426 insertions(+), 173 deletions(-)

diff --git a/pkg/scheduler/objects/predicates.go b/pkg/scheduler/objects/predicates.go
new file mode 100644
index 00000000..039abed7
--- /dev/null
+++ b/pkg/scheduler/objects/predicates.go
@@ -0,0 +1,170 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package objects
+
+import (
+	"fmt"
+	"strings"
+	"sync"
+
+	"go.uber.org/zap"
+
+	"github.com/apache/yunikorn-core/pkg/log"
+	"github.com/apache/yunikorn-scheduler-interface/lib/go/api"
+	"github.com/apache/yunikorn-scheduler-interface/lib/go/si"
+)
+
+type predicateCheckResult struct {
+	allocationKey string
+	nodeID        string
+	success       bool
+	index         int
+	victims       []*Allocation
+}
+
+func (pcr *predicateCheckResult) betterThan(other *predicateCheckResult, allocationsByNode map[string][]*Allocation) bool {
+	return pcr.getSolutionScore(allocationsByNode) < other.getSolutionScore(allocationsByNode)
+}
+
+func (pcr *predicateCheckResult) getSolutionScore(allocationsByNode map[string][]*Allocation) uint64 {
+	if pcr == nil || !pcr.success {
+		return scoreUnfit
+	}
+	allocations, ok := allocationsByNode[pcr.nodeID]
+	if !ok {
+		return scoreUnfit
+	}
+
+	var score uint64 = 0
+	if pcr.index < 0 {
+		return score
+	}
+	if pcr.index >= len(allocations) {
+		// shouldn't happen
+		return scoreUnfit
+	}
+	for i := 0; i <= pcr.index; i++ {
+		allocation := allocations[i]
+		if allocation.IsOriginator() {
+			score |= scoreOriginator
+		}
+		if !allocation.IsAllowPreemptSelf() {
+			score |= scoreNoPreempt
+		}
+	}
+	score += uint64(pcr.index) + 1 // need to add 1 to differentiate between no preemption and preempt 1 container
+
+	return score
+}
+
+func (pcr *predicateCheckResult) isSatisfactory(allocationsByNode map[string][]*Allocation) bool {
+	return pcr.getSolutionScore(allocationsByNode) < scoreFitMax
+}
+
+func (pcr *predicateCheckResult) populateVictims(victimsByNode map[string][]*Allocation) {
+	if pcr == nil {
+		return
+	}
+	pcr.victims = nil
+	if !pcr.success {
+		return
+	}
+
+	// abort if node was not found
+	victimList, ok := victimsByNode[pcr.nodeID]
+	if !ok {
+		log.Log(log.SchedPreemption).Warn("BUG: Unable to find node in victim map", zap.String("nodeID", pcr.nodeID))
+		pcr.success = false
+		pcr.index = -1
+		return
+	}
+
+	// abort if index is too large
+	if pcr.index >= len(victimList) {
+		log.Log(log.SchedPreemption).Warn("BUG: Got invalid index into allocation list",
+			zap.String("nodeID", pcr.nodeID),
+			zap.Int("index", pcr.index),
+			zap.Int("length", len(victimList)))
+		pcr.success = false
+		pcr.index = -1
+		return
+	}
+
+	pcr.victims = make([]*Allocation, 0)
+	for i := 0; i <= pcr.index; i++ {
+		victim := victimList[i]
+		pcr.victims = append(pcr.victims, victim)
+	}
+}
+
+// preemptPredicateCheck performs a single predicate check and reports the resultType on a channel
+func preemptPredicateCheck(plugin api.ResourceManagerCallback, ch chan<- *predicateCheckResult, wg *sync.WaitGroup, args *si.PreemptionPredicatesArgs) {
+	defer wg.Done()
+	result := &predicateCheckResult{
+		allocationKey: args.AllocationKey,
+		nodeID:        args.NodeID,
+		success:       false,
+		index:         -1,
+	}
+	if len(args.PreemptAllocationKeys) == 0 {
+		// normal check; there are sufficient resources to run on this node
+		if err := plugin.Predicates(&si.PredicatesArgs{
+			AllocationKey: args.AllocationKey,
+			NodeID:        args.NodeID,
+			Allocate:      true,
+		}); err == nil {
+			result.success = true
+			result.index = -1
+		} else {
+			log.Log(log.SchedPreemption).Debug("Normal predicate check failed",
+				zap.String("AllocationKey", args.AllocationKey),
+				zap.String("NodeID", args.NodeID),
+				zap.Error(err))
+		}
+	} else if response := plugin.PreemptionPredicates(args); response != nil {
+		// preemption check; at least one allocation will need preemption
+		result.success = response.GetSuccess()
+		if result.success {
+			result.index = int(response.GetIndex())
+		}
+	}
+	ch <- result
+}
+
+func (p *predicateCheckResult) String() string {
+	if p.nodeID == "" {
+		return ""
+	}
+	var result strings.Builder
+	result.WriteString(fmt.Sprintf("node: %s, ", p.nodeID))
+	result.WriteString(fmt.Sprintf("alloc: %s, ", p.allocationKey))
+	result.WriteString(fmt.Sprintf("success: %v, ", p.success))
+	result.WriteString(fmt.Sprintf("index: %d", p.index))
+	if len(p.victims) > 0 {
+		result.WriteString(", victims: [")
+		for i, victim := range p.victims {
+			if i > 0 {
+				result.WriteString(", ")
+			}
+			result.WriteString(victim.String())
+		}
+		result.WriteString("]")
+	}
+	return result.String()
+}
diff --git a/pkg/scheduler/objects/predicates_test.go b/pkg/scheduler/objects/predicates_test.go
new file mode 100644
index 00000000..e8a6ef1d
--- /dev/null
+++ b/pkg/scheduler/objects/predicates_test.go
@@ -0,0 +1,256 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package objects
+
+import (
+	"testing"
+
+	"gotest.tools/v3/assert"
+
+	"github.com/apache/yunikorn-scheduler-interface/lib/go/si"
+)
+
+func TestSolutionScoring(t *testing.T) {
+	singleAlloc := scoreMap(nodeID1, []bool{false}, []bool{true})
+	singleOriginator := scoreMap(nodeID1, []bool{true}, []bool{true})
+	singleNoPreempt := scoreMap(nodeID1, []bool{false}, []bool{false})
+	dual := scoreMap(nodeID1, []bool{true, false}, []bool{true, false})
+
+	var none *predicateCheckResult = nil
+	assert.Equal(t, scoreUnfit, none.getSolutionScore(singleAlloc), "wrong score for nil")
+
+	missing := &predicateCheckResult{nodeID: "missing", success: true, index: 0}
+	assert.Equal(t, scoreUnfit, missing.getSolutionScore(singleAlloc), "wrong score for missing")
+
+	failure := &predicateCheckResult{nodeID: nodeID1, success: false, index: -1}
+	assert.Equal(t, scoreUnfit, failure.getSolutionScore(singleAlloc), "wrong score for failure")
+
+	overrun := &predicateCheckResult{nodeID: nodeID1, success: true, index: 1}
+	assert.Equal(t, scoreUnfit, overrun.getSolutionScore(singleAlloc), "wrong score for overrun")
+
+	noOp := &predicateCheckResult{nodeID: nodeID1, success: true, index: -1}
+	assert.Equal(t, uint64(0), noOp.getSolutionScore(singleAlloc), "wrong score for noop")
+
+	ideal := &predicateCheckResult{nodeID: nodeID1, success: true, index: 0}
+	assert.Equal(t, uint64(1), ideal.getSolutionScore(singleAlloc), "wrong score for ideal")
+
+	originator := &predicateCheckResult{nodeID: nodeID1, success: true, index: 0}
+	assert.Equal(t, scoreOriginator+1, originator.getSolutionScore(singleOriginator), "wrong score for originator")
+
+	noPreempt := &predicateCheckResult{nodeID: nodeID1, success: true, index: 0}
+	assert.Equal(t, scoreNoPreempt+1, noPreempt.getSolutionScore(singleNoPreempt), "wrong score for no-preempt")
+
+	both := &predicateCheckResult{nodeID: nodeID1, success: true, index: 1}
+	assert.Equal(t, scoreOriginator+scoreNoPreempt+2, both.getSolutionScore(dual), "wrong score for both")
+
+	assert.Check(t, noOp.betterThan(none, singleAlloc), "noop should be better than nil")
+	assert.Check(t, noOp.betterThan(ideal, singleAlloc), "noop should be better than ideal")
+}
+
+func TestPredicateCheckResult_String(t *testing.T) {
+	tests := []struct {
+		name   string
+		result *predicateCheckResult
+		want   string
+	}{
+		{
+			name: "empty nodeID",
+			result: &predicateCheckResult{
+				nodeID: "",
+			},
+			want: "",
+		},
+		{
+			name: "basic result without victims",
+			result: &predicateCheckResult{
+				nodeID:        "node-1",
+				allocationKey: "alloc-1",
+				success:       true,
+				index:         0,
+			},
+			want: "node: node-1, alloc: alloc-1, success: true, index: 0",
+		},
+		{
+			name: "result with single victim",
+			result: &predicateCheckResult{
+				nodeID:        "node-1",
+				allocationKey: "alloc-1",
+				success:       true,
+				index:         1,
+				victims: []*Allocation{
+					newAllocationAll("alloc-key-1", "app-1", "node-1", "", nil, false, 0),
+				},
+			},
+			want: "node: node-1, alloc: alloc-1, success: true, index: 1, victims: [allocationKey alloc-key-1, applicationID app-1, Resource map[], Allocated true]",
+		},
+		{
+			name: "result with multiple victims",
+			result: &predicateCheckResult{
+				nodeID:        "node-1",
+				allocationKey: "alloc-1",
+				success:       true,
+				index:         2,
+				victims: []*Allocation{
+					newAllocationAll("alloc-key-1", "app-1", "node-1", "", nil, false, 0),
+					newAllocationAll("alloc-key-2", "app-2", "node-2", "", nil, false, 0),
+				},
+			},
+			want: "node: node-1, alloc: alloc-1, success: true, index: 2, victims: [allocationKey alloc-key-1, applicationID app-1, Resource map[], Allocated true, allocationKey alloc-key-2, applicationID app-2, Resource map[], Allocated true]",
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			got := tt.result.String()
+			assert.Equal(t, tt.want, got)
+		})
+	}
+}
+
+func TestPredicateCheckResult_PopulateVictims(t *testing.T) {
+	tests := []struct {
+		name          string
+		pcr           *predicateCheckResult
+		victimsByNode map[string][]*Allocation
+		wantVictims   []*Allocation
+		wantSuccess   bool
+		wantIndex     int
+	}{
+		{
+			name: "nil predicateCheckResult",
+			pcr:  nil,
+			victimsByNode: map[string][]*Allocation{
+				"node-1": {newAllocation("app-1", "node-1", nil)},
+			},
+			wantVictims: nil,
+			wantSuccess: false,
+			wantIndex:   0,
+		},
+		{
+			name: "unsuccessful result",
+			pcr: &predicateCheckResult{
+				nodeID:  "node-1",
+				success: false,
+				index:   1,
+			},
+			victimsByNode: map[string][]*Allocation{
+				"node-1": {newAllocation("app-1", "node-1", nil)},
+			},
+			wantVictims: nil,
+			wantSuccess: false,
+			wantIndex:   1,
+		},
+		{
+			name: "node not found",
+			pcr: &predicateCheckResult{
+				nodeID:  "node-missing",
+				success: true,
+				index:   0,
+			},
+			victimsByNode: map[string][]*Allocation{
+				"node-1": {newAllocation("app-1", "node-1", nil)},
+			},
+			wantVictims: nil,
+			wantSuccess: false,
+			wantIndex:   -1,
+		},
+		{
+			name: "index too large",
+			pcr: &predicateCheckResult{
+				nodeID:  "node-1",
+				success: true,
+				index:   2,
+			},
+			victimsByNode: map[string][]*Allocation{
+				"node-1": {newAllocation("app-1", "node-1", nil)},
+			},
+			wantVictims: nil,
+			wantSuccess: false,
+			wantIndex:   -1,
+		},
+		{
+			name: "successful population single victim",
+			pcr: &predicateCheckResult{
+				nodeID:  "node-1",
+				success: true,
+				index:   0,
+			},
+			victimsByNode: map[string][]*Allocation{
+				"node-1": {newAllocation("app-1", "node-1", nil)},
+			},
+			wantVictims: []*Allocation{newAllocation("app-1", "node-1", nil)},
+			wantSuccess: true,
+			wantIndex:   0,
+		},
+		{
+			name: "successful population multiple victims",
+			pcr: &predicateCheckResult{
+				nodeID:  "node-1",
+				success: true,
+				index:   1,
+			},
+			victimsByNode: map[string][]*Allocation{
+				"node-1": {
+					newAllocation("app-1", "node-1", nil),
+					newAllocation("app-2", "node-1", nil),
+				},
+			},
+			wantVictims: []*Allocation{
+				newAllocation("app-1", "node-1", nil),
+				newAllocation("app-2", "node-1", nil),
+			},
+			wantSuccess: true,
+			wantIndex:   1,
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			tt.pcr.populateVictims(tt.victimsByNode)
+
+			if tt.pcr != nil {
+				assert.Equal(t, tt.wantSuccess, tt.pcr.success, "success mismatch")
+				assert.Equal(t, tt.wantIndex, tt.pcr.index, "index mismatch")
+				if tt.wantVictims == nil {
+					assert.Assert(t, tt.pcr.victims == nil || len(tt.pcr.victims) == 0, "expected no victims")
+				} else {
+					assert.Equal(t, len(tt.wantVictims), len(tt.pcr.victims), "victims length mismatch")
+				}
+			}
+		})
+	}
+}
+
+func scoreMap(nodeID string, orig, self []bool) map[string][]*Allocation {
+	alloc := make([]*Allocation, 0)
+	for i := range orig {
+		alloc = append(alloc, allocForScore(orig[i], self[i]))
+	}
+	return map[string][]*Allocation{nodeID: alloc}
+}
+
+func allocForScore(originator bool, allowPreemptSelf bool) *Allocation {
+	return NewAllocationFromSI(&si.Allocation{
+		AllocationKey:    "alloc1",
+		ApplicationID:    appID1,
+		Originator:       originator,
+		NodeID:           nodeID1,
+		PreemptionPolicy: &si.PreemptionPolicy{AllowPreemptSelf: allowPreemptSelf},
+	})
+}
diff --git a/pkg/scheduler/objects/preemption.go b/pkg/scheduler/objects/preemption.go
index c70aee4b..0e5bf543 100644
--- a/pkg/scheduler/objects/preemption.go
+++ b/pkg/scheduler/objects/preemption.go
@@ -30,7 +30,6 @@ import (
 	"github.com/apache/yunikorn-core/pkg/common/resources"
 	"github.com/apache/yunikorn-core/pkg/log"
 	"github.com/apache/yunikorn-core/pkg/plugins"
-	"github.com/apache/yunikorn-scheduler-interface/lib/go/api"
 	"github.com/apache/yunikorn-scheduler-interface/lib/go/si"
 )
 
@@ -659,89 +658,6 @@ func (p *Preemptor) TryPreemption() (*AllocationResult, bool) {
 	return newReservedAllocationResult(nodeID, p.ask), true
 }
 
-type predicateCheckResult struct {
-	allocationKey string
-	nodeID        string
-	success       bool
-	index         int
-	victims       []*Allocation
-}
-
-func (pcr *predicateCheckResult) betterThan(other *predicateCheckResult, allocationsByNode map[string][]*Allocation) bool {
-	return pcr.getSolutionScore(allocationsByNode) < other.getSolutionScore(allocationsByNode)
-}
-
-func (pcr *predicateCheckResult) getSolutionScore(allocationsByNode map[string][]*Allocation) uint64 {
-	if pcr == nil || !pcr.success {
-		return scoreUnfit
-	}
-	allocations, ok := allocationsByNode[pcr.nodeID]
-	if !ok {
-		return scoreUnfit
-	}
-
-	var score uint64 = 0
-	if pcr.index < 0 {
-		return score
-	}
-	if pcr.index >= len(allocations) {
-		// shouldn't happen
-		return scoreUnfit
-	}
-	for i := 0; i <= pcr.index; i++ {
-		allocation := allocations[i]
-		if allocation.IsOriginator() {
-			score |= scoreOriginator
-		}
-		if !allocation.IsAllowPreemptSelf() {
-			score |= scoreNoPreempt
-		}
-	}
-	score += uint64(pcr.index) + 1 // need to add 1 to differentiate between no preemption and preempt 1 container
-
-	return score
-}
-
-func (pcr *predicateCheckResult) isSatisfactory(allocationsByNode map[string][]*Allocation) bool {
-	return pcr.getSolutionScore(allocationsByNode) < scoreFitMax
-}
-
-func (pcr *predicateCheckResult) populateVictims(victimsByNode map[string][]*Allocation) {
-	if pcr == nil {
-		return
-	}
-	pcr.victims = nil
-	if !pcr.success {
-		return
-	}
-
-	// abort if node was not found
-	victimList, ok := victimsByNode[pcr.nodeID]
-	if !ok {
-		log.Log(log.SchedPreemption).Warn("BUG: Unable to find node in victim map", zap.String("nodeID", pcr.nodeID))
-		pcr.success = false
-		pcr.index = -1
-		return
-	}
-
-	// abort if index is too large
-	if pcr.index >= len(victimList) {
-		log.Log(log.SchedPreemption).Warn("BUG: Got invalid index into allocation list",
-			zap.String("nodeID", pcr.nodeID),
-			zap.Int("index", pcr.index),
-			zap.Int("length", len(victimList)))
-		pcr.success = false
-		pcr.index = -1
-		return
-	}
-
-	pcr.victims = make([]*Allocation, 0)
-	for i := 0; i <= pcr.index; i++ {
-		victim := victimList[i]
-		pcr.victims = append(pcr.victims, victim)
-	}
-}
-
 // Duplicate creates a copy of this snapshot into the given map by queue path
 func (qps *QueuePreemptionSnapshot) Duplicate(copy map[string]*QueuePreemptionSnapshot) *QueuePreemptionSnapshot {
 	if qps == nil {
@@ -938,40 +854,6 @@ func sortVictimsForPreemption(allocationsByNode map[string][]*Allocation) {
 	}
 }
 
-// preemptPredicateCheck performs a single predicate check and reports the resultType on a channel
-func preemptPredicateCheck(plugin api.ResourceManagerCallback, ch chan<- *predicateCheckResult, wg *sync.WaitGroup, args *si.PreemptionPredicatesArgs) {
-	defer wg.Done()
-	result := &predicateCheckResult{
-		allocationKey: args.AllocationKey,
-		nodeID:        args.NodeID,
-		success:       false,
-		index:         -1,
-	}
-	if len(args.PreemptAllocationKeys) == 0 {
-		// normal check; there are sufficient resources to run on this node
-		if err := plugin.Predicates(&si.PredicatesArgs{
-			AllocationKey: args.AllocationKey,
-			NodeID:        args.NodeID,
-			Allocate:      true,
-		}); err == nil {
-			result.success = true
-			result.index = -1
-		} else {
-			log.Log(log.SchedPreemption).Debug("Normal predicate check failed",
-				zap.String("AllocationKey", args.AllocationKey),
-				zap.String("NodeID", args.NodeID),
-				zap.Error(err))
-		}
-	} else if response := plugin.PreemptionPredicates(args); response != nil {
-		// preemption check; at least one allocation will need preemption
-		result.success = response.GetSuccess()
-		if result.success {
-			result.index = int(response.GetIndex())
-		}
-	}
-	ch <- result
-}
-
 // batchPreemptionChecks splits predicate checks into groups by batch size
 func batchPreemptionChecks(checks []*si.PreemptionPredicatesArgs, batchSize int) [][]*si.PreemptionPredicatesArgs {
 	var result [][]*si.PreemptionPredicatesArgs
diff --git a/pkg/scheduler/objects/preemption_test.go b/pkg/scheduler/objects/preemption_test.go
index e845da92..a88e1bdc 100644
--- a/pkg/scheduler/objects/preemption_test.go
+++ b/pkg/scheduler/objects/preemption_test.go
@@ -1831,58 +1831,3 @@ func TestTryPreemption_OnNode_UGParent_With_UGPreemptorChild_OGVictimChild_As_Si
 	assert.Check(t, !alloc1.IsPreempted(), "alloc1 preempted")
 	assert.Check(t, alloc2.IsPreempted(), "alloc2 not preempted")
 }
-
-func TestSolutionScoring(t *testing.T) {
-	singleAlloc := scoreMap(nodeID1, []bool{false}, []bool{true})
-	singleOriginator := scoreMap(nodeID1, []bool{true}, []bool{true})
-	singleNoPreempt := scoreMap(nodeID1, []bool{false}, []bool{false})
-	dual := scoreMap(nodeID1, []bool{true, false}, []bool{true, false})
-
-	var none *predicateCheckResult = nil
-	assert.Equal(t, scoreUnfit, none.getSolutionScore(singleAlloc), "wrong score for nil")
-
-	missing := &predicateCheckResult{nodeID: "missing", success: true, index: 0}
-	assert.Equal(t, scoreUnfit, missing.getSolutionScore(singleAlloc), "wrong score for missing")
-
-	failure := &predicateCheckResult{nodeID: nodeID1, success: false, index: -1}
-	assert.Equal(t, scoreUnfit, failure.getSolutionScore(singleAlloc), "wrong score for failure")
-
-	overrun := &predicateCheckResult{nodeID: nodeID1, success: true, index: 1}
-	assert.Equal(t, scoreUnfit, overrun.getSolutionScore(singleAlloc), "wrong score for overrun")
-
-	noOp := &predicateCheckResult{nodeID: nodeID1, success: true, index: -1}
-	assert.Equal(t, uint64(0), noOp.getSolutionScore(singleAlloc), "wrong score for noop")
-
-	ideal := &predicateCheckResult{nodeID: nodeID1, success: true, index: 0}
-	assert.Equal(t, uint64(1), ideal.getSolutionScore(singleAlloc), "wrong score for ideal")
-
-	originator := &predicateCheckResult{nodeID: nodeID1, success: true, index: 0}
-	assert.Equal(t, scoreOriginator+1, originator.getSolutionScore(singleOriginator), "wrong score for originator")
-
-	noPreempt := &predicateCheckResult{nodeID: nodeID1, success: true, index: 0}
-	assert.Equal(t, scoreNoPreempt+1, noPreempt.getSolutionScore(singleNoPreempt), "wrong score for no-preempt")
-
-	both := &predicateCheckResult{nodeID: nodeID1, success: true, index: 1}
-	assert.Equal(t, scoreOriginator+scoreNoPreempt+2, both.getSolutionScore(dual), "wrong score for both")
-
-	assert.Check(t, noOp.betterThan(none, singleAlloc), "noop should be better than nil")
-	assert.Check(t, noOp.betterThan(ideal, singleAlloc), "noop should be better than ideal")
-}
-
-func scoreMap(nodeID string, orig, self []bool) map[string][]*Allocation {
-	alloc := make([]*Allocation, 0)
-	for i := range orig {
-		alloc = append(alloc, allocForScore(orig[i], self[i]))
-	}
-	return map[string][]*Allocation{nodeID: alloc}
-}
-
-func allocForScore(originator bool, allowPreemptSelf bool) *Allocation {
-	return NewAllocationFromSI(&si.Allocation{
-		AllocationKey:    "alloc1",
-		ApplicationID:    appID1,
-		Originator:       originator,
-		NodeID:           nodeID1,
-		PreemptionPolicy: &si.PreemptionPolicy{AllowPreemptSelf: allowPreemptSelf},
-	})
-}


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@yunikorn.apache.org
For additional commands, e-mail: issues-help@yunikorn.apache.org