Merge pull request #120534 from pohly/dra-scheduler-ssa-as-fallback
dra scheduler: fall back to SSA for PodSchedulingContext updates
This commit is contained in:
@@ -21,17 +21,21 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
policy "k8s.io/api/policy/v1"
|
||||
resourcev1alpha2 "k8s.io/api/resource/v1alpha2"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/uuid"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
cacheddiscovery "k8s.io/client-go/discovery/cached/memory"
|
||||
"k8s.io/client-go/dynamic"
|
||||
"k8s.io/client-go/dynamic/dynamicinformer"
|
||||
@@ -45,6 +49,7 @@ import (
|
||||
"k8s.io/client-go/scale"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/client-go/tools/events"
|
||||
cliflag "k8s.io/component-base/cli/flag"
|
||||
pvutil "k8s.io/component-helpers/storage/volume"
|
||||
"k8s.io/controller-manager/pkg/informerfactory"
|
||||
"k8s.io/klog/v2"
|
||||
@@ -56,6 +61,7 @@ import (
|
||||
"k8s.io/kubernetes/pkg/controller/namespace"
|
||||
"k8s.io/kubernetes/pkg/controller/resourceclaim"
|
||||
"k8s.io/kubernetes/pkg/controlplane"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
"k8s.io/kubernetes/pkg/scheduler"
|
||||
kubeschedulerconfig "k8s.io/kubernetes/pkg/scheduler/apis/config"
|
||||
configtesting "k8s.io/kubernetes/pkg/scheduler/apis/config/testing"
|
||||
@@ -239,8 +245,15 @@ func CreateNamespaceController(ctx context.Context, tb testing.TB, restConfig re
|
||||
}
|
||||
}
|
||||
|
||||
// TestContext store necessary context info
|
||||
// TestContext store necessary context info.
|
||||
// It also contains some optional parameters for InitTestScheduler.
|
||||
type TestContext struct {
|
||||
// DisableEventSink, if set to true before calling InitTestScheduler,
|
||||
// will skip the eventBroadcaster.StartRecordingToSink and thus
|
||||
// some extra goroutines which are tricky to get rid of after
|
||||
// a test.
|
||||
DisableEventSink bool
|
||||
|
||||
NS *v1.Namespace
|
||||
ClientSet clientset.Interface
|
||||
KubeConfig *restclient.Config
|
||||
@@ -257,8 +270,29 @@ type TestContext struct {
|
||||
// SchedulerCloseFn will tear down the resources in creating scheduler,
|
||||
// including the scheduler itself.
|
||||
SchedulerCloseFn framework.TearDownFunc
|
||||
|
||||
// RoundTrip, if set, will be called for every HTTP request going to the apiserver.
|
||||
// It can be used for error injection.
|
||||
RoundTrip atomic.Pointer[RoundTripWrapper]
|
||||
}
|
||||
|
||||
type RoundTripWrapper func(http.RoundTripper, *http.Request) (*http.Response, error)
|
||||
|
||||
type roundTripWrapper struct {
|
||||
tc *TestContext
|
||||
transport http.RoundTripper
|
||||
}
|
||||
|
||||
func (r roundTripWrapper) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
wrapper := r.tc.RoundTrip.Load()
|
||||
if wrapper != nil {
|
||||
return (*wrapper)(r.transport, req)
|
||||
}
|
||||
return r.transport.RoundTrip(req)
|
||||
}
|
||||
|
||||
var _ http.RoundTripper = roundTripWrapper{}
|
||||
|
||||
// CleanupNodes cleans all nodes which were created during integration test
|
||||
func CleanupNodes(cs clientset.Interface, t *testing.T) {
|
||||
err := cs.CoreV1().Nodes().DeleteCollection(context.TODO(), *metav1.NewDeleteOptions(0), metav1.ListOptions{})
|
||||
@@ -468,11 +502,16 @@ func UpdateNodeStatus(cs clientset.Interface, node *v1.Node) error {
|
||||
func InitTestAPIServer(t *testing.T, nsPrefix string, admission admission.Interface) *TestContext {
|
||||
_, ctx := ktesting.NewTestContext(t)
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
testCtx := TestContext{Ctx: ctx}
|
||||
testCtx := &TestContext{Ctx: ctx}
|
||||
|
||||
testCtx.ClientSet, testCtx.KubeConfig, testCtx.CloseFn = framework.StartTestServer(ctx, t, framework.TestServerSetup{
|
||||
ModifyServerRunOptions: func(options *options.ServerRunOptions) {
|
||||
options.Admission.GenericAdmission.DisablePlugins = []string{"ServiceAccount", "TaintNodesByCondition", "Priority", "StorageObjectInUseProtection"}
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.DynamicResourceAllocation) {
|
||||
options.APIEnablement.RuntimeConfig = cliflag.ConfigurationMap{
|
||||
resourcev1alpha2.SchemeGroupVersion.String(): "true",
|
||||
}
|
||||
}
|
||||
},
|
||||
ModifyServerConfig: func(config *controlplane.Config) {
|
||||
if admission != nil {
|
||||
@@ -481,6 +520,16 @@ func InitTestAPIServer(t *testing.T, nsPrefix string, admission admission.Interf
|
||||
},
|
||||
})
|
||||
|
||||
// Support wrapping HTTP requests.
|
||||
testCtx.KubeConfig.Wrap(func(transport http.RoundTripper) http.RoundTripper {
|
||||
return roundTripWrapper{tc: testCtx, transport: transport}
|
||||
})
|
||||
var err error
|
||||
testCtx.ClientSet, err = clientset.NewForConfig(testCtx.KubeConfig)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
oldCloseFn := testCtx.CloseFn
|
||||
testCtx.CloseFn = func() {
|
||||
cancel()
|
||||
@@ -494,10 +543,10 @@ func InitTestAPIServer(t *testing.T, nsPrefix string, admission admission.Interf
|
||||
}
|
||||
|
||||
t.Cleanup(func() {
|
||||
CleanupTest(t, &testCtx)
|
||||
CleanupTest(t, testCtx)
|
||||
})
|
||||
|
||||
return &testCtx
|
||||
return testCtx
|
||||
}
|
||||
|
||||
// WaitForSchedulerCacheCleanup waits for cleanup of scheduler's cache to complete
|
||||
@@ -560,7 +609,9 @@ func InitTestSchedulerWithOptions(
|
||||
t.Fatalf("Couldn't create scheduler: %v", err)
|
||||
}
|
||||
|
||||
eventBroadcaster.StartRecordingToSink(ctx.Done())
|
||||
if !testCtx.DisableEventSink {
|
||||
eventBroadcaster.StartRecordingToSink(ctx.Done())
|
||||
}
|
||||
|
||||
oldCloseFn := testCtx.CloseFn
|
||||
testCtx.CloseFn = func() {
|
||||
|
Reference in New Issue
Block a user