mirror of
https://github.com/k3s-io/kubernetes.git
synced 2026-07-18 22:40:35 +00:00
Fit tests: add DRA-aware test cases
This commit is contained in:
@@ -29,6 +29,7 @@ import (
|
||||
resourceapi "k8s.io/api/resource/v1"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
apiruntime "k8s.io/apimachinery/pkg/runtime"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/client-go/informers"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
@@ -1031,6 +1032,7 @@ func TestFitScore(t *testing.T) {
|
||||
expectedPriorities fwk.NodeScoreList
|
||||
nodeResourcesFitArgs config.NodeResourcesFitArgs
|
||||
runPreScore bool
|
||||
draObjects []apiruntime.Object
|
||||
}{
|
||||
{
|
||||
name: "test case for ScoringStrategy RequestedToCapacityRatio case1",
|
||||
@@ -1250,11 +1252,57 @@ func TestFitScore(t *testing.T) {
|
||||
},
|
||||
runPreScore: true,
|
||||
},
|
||||
{
|
||||
name: "test case for ScoringStrategy LeastAllocated with Extended resources",
|
||||
requestedPod: st.MakePod().Req(map[v1.ResourceName]string{extendedResourceDRA: "1"}).Obj(),
|
||||
nodes: []*v1.Node{
|
||||
st.MakeNode().Name("node1").Obj(),
|
||||
st.MakeNode().Name("node2").Obj(),
|
||||
},
|
||||
expectedPriorities: []fwk.NodeScore{{Name: "node1", Score: 66}, {Name: "node2", Score: 50}},
|
||||
draObjects: []apiruntime.Object{
|
||||
deviceClassWithExtendResourceName,
|
||||
st.MakeResourceSlice("node1", "test-driver").Device("device-1").Device("device-2").Device("device-3").Obj(),
|
||||
st.MakeResourceSlice("node2", "test-driver").Device("device-1").Device("device-2").Obj(),
|
||||
},
|
||||
nodeResourcesFitArgs: config.NodeResourcesFitArgs{
|
||||
ScoringStrategy: &config.ScoringStrategy{
|
||||
Type: config.LeastAllocated,
|
||||
Resources: []config.ResourceSpec{
|
||||
{Name: extendedResourceName, Weight: 1},
|
||||
},
|
||||
},
|
||||
},
|
||||
runPreScore: true,
|
||||
},
|
||||
{
|
||||
name: "test case for ScoringStrategy LeastAllocated with Extended resources if PreScore is not called",
|
||||
requestedPod: st.MakePod().Req(map[v1.ResourceName]string{extendedResourceDRA: "1"}).Obj(),
|
||||
nodes: []*v1.Node{
|
||||
st.MakeNode().Name("node1").Obj(),
|
||||
st.MakeNode().Name("node2").Obj(),
|
||||
},
|
||||
expectedPriorities: []fwk.NodeScore{{Name: "node1", Score: 66}, {Name: "node2", Score: 50}},
|
||||
draObjects: []apiruntime.Object{
|
||||
deviceClassWithExtendResourceName,
|
||||
st.MakeResourceSlice("node1", "test-driver").Device("device-1").Device("device-2").Device("device-3").Obj(),
|
||||
st.MakeResourceSlice("node2", "test-driver").Device("device-1").Device("device-2").Obj(),
|
||||
},
|
||||
nodeResourcesFitArgs: config.NodeResourcesFitArgs{
|
||||
ScoringStrategy: &config.ScoringStrategy{
|
||||
Type: config.LeastAllocated,
|
||||
Resources: []config.ResourceSpec{
|
||||
{Name: extendedResourceName, Weight: 1},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
_, ctx := ktesting.NewTestContext(t)
|
||||
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DRAExtendedResource, test.draObjects != nil)
|
||||
logger, ctx := ktesting.NewTestContext(t)
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
defer cancel()
|
||||
|
||||
@@ -1262,11 +1310,21 @@ func TestFitScore(t *testing.T) {
|
||||
snapshot := cache.NewSnapshot(test.existingPods, test.nodes)
|
||||
fh, _ := runtime.NewFramework(ctx, nil, nil, runtime.WithSnapshotSharedLister(snapshot))
|
||||
args := test.nodeResourcesFitArgs
|
||||
p, err := NewFit(ctx, &args, fh, plfeature.Features{})
|
||||
p, err := NewFit(ctx, &args, fh, plfeature.Features{
|
||||
EnableDRAExtendedResource: test.draObjects != nil,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if test.draObjects != nil {
|
||||
draManager, err := newTestDRAManager(t, ctx, logger, test.draObjects...)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create test DRA manager: %v", err)
|
||||
}
|
||||
p.(*Fit).draManager = draManager
|
||||
}
|
||||
|
||||
var gotPriorities fwk.NodeScoreList
|
||||
for _, n := range test.nodes {
|
||||
if test.runPreScore {
|
||||
@@ -2143,3 +2201,92 @@ func TestHaveAnyRequestedResourcesIncreased(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestFitSignPod(t *testing.T) {
|
||||
tests := map[string]struct {
|
||||
name string
|
||||
pod *v1.Pod
|
||||
enableDRAExtendedResource bool
|
||||
expectedFragments []fwk.SignFragment
|
||||
expectedStatusCode fwk.Code
|
||||
}{
|
||||
"pod with CPU and memory requests": {
|
||||
pod: st.MakePod().Req(map[v1.ResourceName]string{
|
||||
v1.ResourceCPU: "1000m",
|
||||
v1.ResourceMemory: "2000",
|
||||
}).Obj(),
|
||||
enableDRAExtendedResource: false,
|
||||
expectedFragments: []fwk.SignFragment{
|
||||
{Key: fwk.ResourcesSignerName, Value: computePodResourceRequest(st.MakePod().Req(map[v1.ResourceName]string{
|
||||
v1.ResourceCPU: "1000m",
|
||||
v1.ResourceMemory: "2000",
|
||||
}).Obj(), ResourceRequestsOptions{})},
|
||||
},
|
||||
expectedStatusCode: fwk.Success,
|
||||
},
|
||||
"best-effort pod with no requests": {
|
||||
pod: st.MakePod().Obj(),
|
||||
enableDRAExtendedResource: false,
|
||||
expectedFragments: []fwk.SignFragment{
|
||||
{Key: fwk.ResourcesSignerName, Value: computePodResourceRequest(st.MakePod().Obj(), ResourceRequestsOptions{})},
|
||||
},
|
||||
expectedStatusCode: fwk.Success,
|
||||
},
|
||||
"pod with multiple containers": {
|
||||
pod: st.MakePod().Container("container1").Req(map[v1.ResourceName]string{
|
||||
v1.ResourceCPU: "500m",
|
||||
v1.ResourceMemory: "1000",
|
||||
}).Container("container2").Req(map[v1.ResourceName]string{
|
||||
v1.ResourceCPU: "1500m",
|
||||
v1.ResourceMemory: "3000",
|
||||
}).Obj(),
|
||||
enableDRAExtendedResource: false,
|
||||
expectedFragments: []fwk.SignFragment{
|
||||
{Key: fwk.ResourcesSignerName, Value: computePodResourceRequest(st.MakePod().Container("container1").Req(map[v1.ResourceName]string{
|
||||
v1.ResourceCPU: "500m",
|
||||
v1.ResourceMemory: "1000",
|
||||
}).Container("container2").Req(map[v1.ResourceName]string{
|
||||
v1.ResourceCPU: "1500m",
|
||||
v1.ResourceMemory: "3000",
|
||||
}).Obj(), ResourceRequestsOptions{})},
|
||||
},
|
||||
expectedStatusCode: fwk.Success,
|
||||
},
|
||||
"DRA extended resource enabled - returns unschedulable": {
|
||||
pod: st.MakePod().Req(map[v1.ResourceName]string{
|
||||
v1.ResourceCPU: "1000m",
|
||||
v1.ResourceMemory: "2000",
|
||||
}).Obj(),
|
||||
enableDRAExtendedResource: true,
|
||||
expectedFragments: nil,
|
||||
expectedStatusCode: fwk.Unschedulable,
|
||||
},
|
||||
}
|
||||
|
||||
for name, test := range tests {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
_, ctx := ktesting.NewTestContext(t)
|
||||
|
||||
fh, _ := runtime.NewFramework(ctx, nil, nil)
|
||||
p, err := NewFit(ctx, &config.NodeResourcesFitArgs{ScoringStrategy: defaultScoringStrategy}, fh, plfeature.Features{
|
||||
EnableDRAExtendedResource: test.enableDRAExtendedResource,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create plugin: %v", err)
|
||||
}
|
||||
|
||||
fit := p.(*Fit)
|
||||
fragments, status := fit.SignPod(ctx, test.pod)
|
||||
|
||||
if status.Code() != test.expectedStatusCode {
|
||||
t.Errorf("unexpected status code, want: %v, got: %v, message: %v", test.expectedStatusCode, status.Code(), status.Message())
|
||||
}
|
||||
|
||||
if test.expectedStatusCode == fwk.Success {
|
||||
if diff := cmp.Diff(test.expectedFragments, fragments); diff != "" {
|
||||
t.Errorf("unexpected fragments, diff (-want,+got):\n%s", diff)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user