Repository: kubernetes-sigs/scheduler-plugins
Pull request #896 (2025-04-27 06:25:55)

Automated cherry pick of #895: Compose a cached reader as a cacheOption when initializing a
Cherry pick of #895 on release-1.30.

#895: Compose a cached reader as a cacheOption when initializing a

For details on the cherry pick process, see the [cherry pick requests](https://git.k8s.io/community/contributors/devel/sig-release/cherry-picks.md) page.

```release-note
Compose a cached reader as a cacheOption when initializing a controller-runtime client
```

k8s-ci-robot: [APPROVALNOTIFIER] This PR is **NOT APPROVED**

This pull-request has been approved by: *<a href="https://github.com/kubernetes-sigs/scheduler-plugins/pull/896#" title="Author self-approved">googs1025</a>*
**Once this PR has been reviewed and has the lgtm label**, please assign [huang-wei](https://github.com/huang-wei) for approval. For more information see [the Code Review Process](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process).

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=kubernetes-sigs%2Fscheduler-plugins).

<details open>
Needs approval from an approver in each of these files:

- **[OWNERS](https://github.com/kubernetes-sigs/scheduler-plugins/blob/release-1.30/OWNERS)**

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":["huang-wei"]} -->
googs1025: /assign @Huang-Wei 
k8s-ci-robot: @googs1025: The following test **failed**, say `/retest` to rerun all failed tests or `/retest-required` to rerun all mandatory failed tests:

Test name | Commit | Details | Required | Rerun command
--- | --- | --- | --- | ---
pull-scheduler-plugins-verify-build-release-1-30 | 5fa48cb69060c2442a8d5f0ff9153eebcf16a2b9 | [link](https://prow.k8s.io/view/gs/kubernetes-ci-logs/pr-logs/pull/kubernetes-sigs_scheduler-plugins/896/pull-scheduler-plugins-verify-build-release-1-30/1916378264209723392) | true | `/test pull-scheduler-plugins-verify-build-release-1-30`

[Full PR test history](https://prow.k8s.io/pr-history?org=kubernetes-sigs&repo=scheduler-plugins&pr=896). [Your PR dashboard](https://prow.k8s.io/pr?query=is%3Apr%20state%3Aopen%20author%3Agoogs1025). Please help us cut down on flakes by [linking to](https://git.k8s.io/community/contributors/devel/sig-testing/flaky-tests.md#filing-issues-for-flaky-tests) an [open issue](https://github.com/kubernetes-sigs/scheduler-plugins/issues?q=is:issue+is:open) when you hit one in your PR.

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes-sigs/prow](https://github.com/kubernetes-sigs/prow/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
k8s-ci-robot: @googs1025: The following tests **failed**, say `/retest` to rerun all failed tests or `/retest-required` to rerun all mandatory failed tests:

Test name | Commit | Details | Required | Rerun command
--- | --- | --- | --- | ---
pull-scheduler-plugins-verify-build-release-1-30 | 5fa48cb69060c2442a8d5f0ff9153eebcf16a2b9 | [link](https://prow.k8s.io/view/gs/kubernetes-ci-logs/pr-logs/pull/kubernetes-sigs_scheduler-plugins/896/pull-scheduler-plugins-verify-build-release-1-30/1916378264209723392) | true | `/test pull-scheduler-plugins-verify-build-release-1-30`
pull-scheduler-plugins-integration-test-release-1-30 | 5fa48cb69060c2442a8d5f0ff9153eebcf16a2b9 | [link](https://prow.k8s.io/view/gs/kubernetes-ci-logs/pr-logs/pull/kubernetes-sigs_scheduler-plugins/896/pull-scheduler-plugins-integration-test-release-1-30/1916378264327163904) | true | `/test pull-scheduler-plugins-integration-test-release-1-30`

[Full PR test history](https://prow.k8s.io/pr-history?org=kubernetes-sigs&repo=scheduler-plugins&pr=896). [Your PR dashboard](https://prow.k8s.io/pr?query=is%3Apr%20state%3Aopen%20author%3Agoogs1025). Please help us cut down on flakes by [linking to](https://git.k8s.io/community/contributors/devel/sig-testing/flaky-tests.md#filing-issues-for-flaky-tests) an [open issue](https://github.com/kubernetes-sigs/scheduler-plugins/issues?q=is:issue+is:open) when you hit one in your PR.

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes-sigs/prow](https://github.com/kubernetes-sigs/prow/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
k8s-ci-robot: @googs1025: The following tests **failed**, say `/retest` to rerun all failed tests or `/retest-required` to rerun all mandatory failed tests:

Test name | Commit | Details | Required | Rerun command
--- | --- | --- | --- | ---
pull-scheduler-plugins-verify-build-release-1-30 | 5fa48cb69060c2442a8d5f0ff9153eebcf16a2b9 | [link](https://prow.k8s.io/view/gs/kubernetes-ci-logs/pr-logs/pull/kubernetes-sigs_scheduler-plugins/896/pull-scheduler-plugins-verify-build-release-1-30/1916378264209723392) | true | `/test pull-scheduler-plugins-verify-build-release-1-30`
pull-scheduler-plugins-integration-test-release-1-30 | 5fa48cb69060c2442a8d5f0ff9153eebcf16a2b9 | [link](https://prow.k8s.io/view/gs/kubernetes-ci-logs/pr-logs/pull/kubernetes-sigs_scheduler-plugins/896/pull-scheduler-plugins-integration-test-release-1-30/1916378264327163904) | true | `/test pull-scheduler-plugins-integration-test-release-1-30`
pull-scheduler-plugins-unit-test-release-1-30 | 5fa48cb69060c2442a8d5f0ff9153eebcf16a2b9 | [link](https://prow.k8s.io/view/gs/kubernetes-ci-logs/pr-logs/pull/kubernetes-sigs_scheduler-plugins/896/pull-scheduler-plugins-unit-test-release-1-30/1916378264268443648) | true | `/test pull-scheduler-plugins-unit-test-release-1-30`

[Full PR test history](https://prow.k8s.io/pr-history?org=kubernetes-sigs&repo=scheduler-plugins&pr=896). [Your PR dashboard](https://prow.k8s.io/pr?query=is%3Apr%20state%3Aopen%20author%3Agoogs1025). Please help us cut down on flakes by [linking to](https://git.k8s.io/community/contributors/devel/sig-testing/flaky-tests.md#filing-issues-for-flaky-tests) an [open issue](https://github.com/kubernetes-sigs/scheduler-plugins/issues?q=is:issue+is:open) when you hit one in your PR.

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes-sigs/prow](https://github.com/kubernetes-sigs/prow/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
k8s-ci-robot: [APPROVALNOTIFIER] This PR is **NOT APPROVED**

This pull-request has been approved by: *<a href="https://github.com/kubernetes-sigs/scheduler-plugins/pull/896#" title="Author self-approved">googs1025</a>*
**Once this PR has been reviewed and has the lgtm label**, please ask for approval from [huang-wei](https://github.com/huang-wei). For more information see [the Code Review Process](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process).

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=kubernetes-sigs%2Fscheduler-plugins).

<details open>
Needs approval from an approver in each of these files:

- **[OWNERS](https://github.com/kubernetes-sigs/scheduler-plugins/blob/release-1.30/OWNERS)**

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":["huang-wei"]} -->

Patch:
diff --git a/pkg/capacityscheduling/capacity_scheduling.go b/pkg/capacityscheduling/capacity_scheduling.go
index f9b8fb34..af6a1276 100644
--- a/pkg/capacityscheduling/capacity_scheduling.go
+++ b/pkg/capacityscheduling/capacity_scheduling.go
@@ -40,7 +40,6 @@ import (
 	"k8s.io/kubernetes/pkg/scheduler/framework/preemption"
 	"k8s.io/kubernetes/pkg/scheduler/metrics"
 	schedutil "k8s.io/kubernetes/pkg/scheduler/util"
-	ctrlruntimecache "sigs.k8s.io/controller-runtime/pkg/cache"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
 	"sigs.k8s.io/scheduler-plugins/apis/scheduling"
@@ -127,18 +126,14 @@ func New(ctx context.Context, obj runtime.Object, handle framework.Handle) (fram
 	}
 	logger := klog.FromContext(ctx)
 
-	client, err := client.New(handle.KubeConfig(), client.Options{Scheme: scheme})
+	client, ccache, err := util.NewClientWithCachedReader(ctx, handle.KubeConfig(), scheme)
 	if err != nil {
 		return nil, err
 	}
 
 	c.client = client
-	dynamicCache, err := ctrlruntimecache.New(handle.KubeConfig(), ctrlruntimecache.Options{Scheme: scheme})
-	if err != nil {
-		return nil, err
-	}
 
-	elasticQuotaInformer, err := dynamicCache.GetInformer(ctx, &v1alpha1.ElasticQuota{})
+	elasticQuotaInformer, err := ccache.GetInformer(ctx, &v1alpha1.ElasticQuota{})
 	if err != nil {
 		return nil, err
 	}
diff --git a/pkg/coscheduling/coscheduling.go b/pkg/coscheduling/coscheduling.go
index 69b36175..96d68b45 100644
--- a/pkg/coscheduling/coscheduling.go
+++ b/pkg/coscheduling/coscheduling.go
@@ -29,7 +29,6 @@ import (
 	corev1helpers "k8s.io/component-helpers/scheduling/corev1"
 	"k8s.io/klog/v2"
 	"k8s.io/kubernetes/pkg/scheduler/framework"
-	"sigs.k8s.io/controller-runtime/pkg/client"
 
 	"sigs.k8s.io/scheduler-plugins/apis/config"
 	"sigs.k8s.io/scheduler-plugins/apis/scheduling"
@@ -74,7 +73,7 @@ func New(ctx context.Context, obj runtime.Object, handle framework.Handle) (fram
 	_ = clientscheme.AddToScheme(scheme)
 	_ = v1.AddToScheme(scheme)
 	_ = v1alpha1.AddToScheme(scheme)
-	client, err := client.New(handle.KubeConfig(), client.Options{Scheme: scheme})
+	c, _, err := util.NewClientWithCachedReader(ctx, handle.KubeConfig(), scheme)
 	if err != nil {
 		return nil, err
 	}
@@ -84,7 +83,7 @@ func New(ctx context.Context, obj runtime.Object, handle framework.Handle) (fram
 
 	scheduleTimeDuration := time.Duration(args.PermitWaitingTimeSeconds) * time.Second
 	pgMgr := core.NewPodGroupManager(
-		client,
+		c,
 		handle.SnapshotSharedLister(),
 		&scheduleTimeDuration,
 		// Keep the podInformer (from frameworkHandle) as the single source of Pods.
diff --git a/pkg/networkaware/networkoverhead/networkoverhead.go b/pkg/networkaware/networkoverhead/networkoverhead.go
index 242e0a62..0b8422d5 100644
--- a/pkg/networkaware/networkoverhead/networkoverhead.go
+++ b/pkg/networkaware/networkoverhead/networkoverhead.go
@@ -30,11 +30,11 @@ import (
 	corelisters "k8s.io/client-go/listers/core/v1"
 	"k8s.io/klog/v2"
 	"k8s.io/kubernetes/pkg/scheduler/framework"
-
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
 	pluginconfig "sigs.k8s.io/scheduler-plugins/apis/config"
 	networkawareutil "sigs.k8s.io/scheduler-plugins/pkg/networkaware/util"
+	"sigs.k8s.io/scheduler-plugins/pkg/util"
 
 	agv1alpha1 "github.com/diktyo-io/appgroup-api/pkg/apis/appgroup/v1alpha1"
 	ntv1alpha1 "github.com/diktyo-io/networktopology-api/pkg/apis/networktopology/v1alpha1"
@@ -147,16 +147,13 @@ func New(ctx context.Context, obj runtime.Object, handle framework.Handle) (fram
 	if err != nil {
 		return nil, err
 	}
-	client, err := client.New(handle.KubeConfig(), client.Options{
-		Scheme: scheme,
-	})
+	c, _, err := util.NewClientWithCachedReader(ctx, handle.KubeConfig(), scheme)
 	if err != nil {
 		return nil, err
 	}
 
 	no := &NetworkOverhead{
-		Client: client,
-
+		Client:      c,
 		podLister:   handle.SharedInformerFactory().Core().V1().Pods().Lister(),
 		handle:      handle,
 		namespaces:  args.Namespaces,
diff --git a/pkg/networkaware/topologicalsort/topologicalsort.go b/pkg/networkaware/topologicalsort/topologicalsort.go
index a360347e..c910c980 100644
--- a/pkg/networkaware/topologicalsort/topologicalsort.go
+++ b/pkg/networkaware/topologicalsort/topologicalsort.go
@@ -26,11 +26,11 @@ import (
 	"k8s.io/klog/v2"
 	"k8s.io/kubernetes/pkg/scheduler/framework"
 	"k8s.io/kubernetes/pkg/scheduler/framework/plugins/queuesort"
-
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
 	pluginconfig "sigs.k8s.io/scheduler-plugins/apis/config"
 	networkawareutil "sigs.k8s.io/scheduler-plugins/pkg/networkaware/util"
+	"sigs.k8s.io/scheduler-plugins/pkg/util"
 
 	agv1alpha "github.com/diktyo-io/appgroup-api/pkg/apis/appgroup/v1alpha1"
 )
@@ -81,15 +81,13 @@ func New(ctx context.Context, obj runtime.Object, handle framework.Handle) (fram
 		return nil, err
 	}
 
-	client, err := client.New(handle.KubeConfig(), client.Options{
-		Scheme: scheme,
-	})
+	c, _, err := util.NewClientWithCachedReader(ctx, handle.KubeConfig(), scheme)
 	if err != nil {
 		return nil, err
 	}
 
 	pl := &TopologicalSort{
-		Client:     client,
+		Client:     c,
 		handle:     handle,
 		namespaces: args.Namespaces,
 	}
diff --git a/pkg/sysched/sysched.go b/pkg/sysched/sysched.go
index 4f8359f1..a84d6328 100644
--- a/pkg/sysched/sysched.go
+++ b/pkg/sysched/sysched.go
@@ -22,6 +22,7 @@ import (
 
 	pluginconfig "sigs.k8s.io/scheduler-plugins/apis/config"
 	"sigs.k8s.io/scheduler-plugins/apis/scheduling/v1alpha1"
+	"sigs.k8s.io/scheduler-plugins/pkg/util"
 )
 
 type SySched struct {
@@ -402,7 +403,7 @@ func getArgs(obj runtime.Object) (*pluginconfig.SySchedArgs, error) {
 }
 
 // New initializes a new plugin and returns it.
-func New(_ context.Context, obj runtime.Object, handle framework.Handle) (framework.Plugin, error) {
+func New(ctx context.Context, obj runtime.Object, handle framework.Handle) (framework.Plugin, error) {
 	sc := SySched{handle: handle}
 	sc.HostToPods = make(map[string][]*v1.Pod)
 	sc.HostSyscalls = make(map[string]sets.Set[string])
@@ -425,12 +426,12 @@ func New(_ context.Context, obj runtime.Object, handle framework.Handle) (framew
 
 	v1beta1.AddToScheme(scheme)
 
-	client, err := client.New(handle.KubeConfig(), client.Options{Scheme: scheme})
+	c, _, err := util.NewClientWithCachedReader(ctx, handle.KubeConfig(), scheme)
 	if err != nil {
 		return nil, err
 	}
 
-	sc.client = client
+	sc.client = c
 
 	podInformer := handle.SharedInformerFactory().Core().V1().Pods()
 
diff --git a/pkg/util/client_util.go b/pkg/util/client_util.go
new file mode 100644
index 00000000..6da2b209
--- /dev/null
+++ b/pkg/util/client_util.go
@@ -0,0 +1,32 @@
+package util
+
+import (
+	"context"
+	"fmt"
+
+	"k8s.io/apimachinery/pkg/runtime"
+	"k8s.io/client-go/rest"
+	"sigs.k8s.io/controller-runtime/pkg/cache"
+	"sigs.k8s.io/controller-runtime/pkg/client"
+)
+
+// NewClientWithCachedReader returns a controller runtime Client with cache-baked client.
+func NewClientWithCachedReader(ctx context.Context, config *rest.Config, scheme *runtime.Scheme) (client.Client, cache.Cache, error) {
+	ccache, err := cache.New(config, cache.Options{
+		Scheme: scheme,
+	})
+	if err != nil {
+		return nil, nil, err
+	}
+	go ccache.Start(ctx)
+	if !ccache.WaitForCacheSync(ctx) {
+		return nil, nil, fmt.Errorf("failed to sync cache")
+	}
+	c, err := client.New(config, client.Options{
+		Scheme: scheme,
+		Cache: &client.CacheOptions{
+			Reader: ccache,
+		},
+	})
+	return c, ccache, err
+}


Test patch:
diff --git a/test/integration/capacity_scheduling_test.go b/test/integration/capacity_scheduling_test.go
index c5de3bd0..f3873774 100644
--- a/test/integration/capacity_scheduling_test.go
+++ b/test/integration/capacity_scheduling_test.go
@@ -44,7 +44,7 @@ func TestCapacityScheduling(t *testing.T) {
 	testCtx.Ctx, testCtx.CancelFn = context.WithCancel(context.Background())
 
 	cs := kubernetes.NewForConfigOrDie(globalKubeConfig)
-	extClient := util.NewClientOrDie(globalKubeConfig)
+	extClient := util.NewClientOrDie(testCtx.Ctx, globalKubeConfig)
 	testCtx.ClientSet = cs
 	testCtx.KubeConfig = globalKubeConfig
 
diff --git a/test/integration/coscheduling_test.go b/test/integration/coscheduling_test.go
index 008fed4b..989dfc55 100644
--- a/test/integration/coscheduling_test.go
+++ b/test/integration/coscheduling_test.go
@@ -49,7 +49,7 @@ func TestCoschedulingPlugin(t *testing.T) {
 	testCtx.Ctx, testCtx.CancelFn = context.WithCancel(context.Background())
 
 	cs := kubernetes.NewForConfigOrDie(globalKubeConfig)
-	extClient := util.NewClientOrDie(globalKubeConfig)
+	extClient := util.NewClientOrDie(testCtx.Ctx, globalKubeConfig)
 	testCtx.ClientSet = cs
 	testCtx.KubeConfig = globalKubeConfig
 
@@ -382,7 +382,7 @@ func TestPodgroupBackoff(t *testing.T) {
 	testCtx.Ctx, testCtx.CancelFn = context.WithCancel(context.Background())
 
 	cs := kubernetes.NewForConfigOrDie(globalKubeConfig)
-	extClient := util.NewClientOrDie(globalKubeConfig)
+	extClient := util.NewClientOrDie(testCtx.Ctx, globalKubeConfig)
 	testCtx.ClientSet = cs
 	testCtx.KubeConfig = globalKubeConfig
 
diff --git a/test/integration/elasticquota_controller_test.go b/test/integration/elasticquota_controller_test.go
index 65f7813e..901313c6 100644
--- a/test/integration/elasticquota_controller_test.go
+++ b/test/integration/elasticquota_controller_test.go
@@ -51,7 +51,7 @@ func TestElasticController(t *testing.T) {
 	testCtx.Ctx, testCtx.CancelFn = context.WithCancel(context.Background())
 
 	cs := kubernetes.NewForConfigOrDie(globalKubeConfig)
-	extClient := util.NewClientOrDie(globalKubeConfig)
+	extClient := util.NewClientOrDie(testCtx.Ctx, globalKubeConfig)
 	testCtx.ClientSet = cs
 	testCtx.KubeConfig = globalKubeConfig
 
diff --git a/test/integration/networkoverhead_test.go b/test/integration/networkoverhead_test.go
index 26c3ed77..25d2d31f 100644
--- a/test/integration/networkoverhead_test.go
+++ b/test/integration/networkoverhead_test.go
@@ -37,11 +37,10 @@ import (
 	st "k8s.io/kubernetes/pkg/scheduler/testing"
 	imageutils "k8s.io/kubernetes/test/utils/image"
 
-	ctrlclient "sigs.k8s.io/controller-runtime/pkg/client"
-
 	scheconfig "sigs.k8s.io/scheduler-plugins/apis/config"
 	"sigs.k8s.io/scheduler-plugins/pkg/networkaware/networkoverhead"
 	networkawareutil "sigs.k8s.io/scheduler-plugins/pkg/networkaware/util"
+	clientutil "sigs.k8s.io/scheduler-plugins/pkg/util"
 	"sigs.k8s.io/scheduler-plugins/test/util"
 
 	appgroupapi "github.com/diktyo-io/appgroup-api/pkg/apis/appgroup"
@@ -59,7 +58,7 @@ func TestNetworkOverheadPlugin(t *testing.T) {
 	utilruntime.Must(agv1alpha1.AddToScheme(scheme))
 	utilruntime.Must(ntv1alpha1.AddToScheme(scheme))
 
-	client, err := ctrlclient.New(globalKubeConfig, ctrlclient.Options{Scheme: scheme})
+	client, _, err := clientutil.NewClientWithCachedReader(testCtx.Ctx, globalKubeConfig, scheme)
 
 	cs := kubernetes.NewForConfigOrDie(globalKubeConfig)
 	testCtx.ClientSet = cs
diff --git a/test/integration/podgroup_controller_test.go b/test/integration/podgroup_controller_test.go
index ae3653e8..a9a9d7da 100644
--- a/test/integration/podgroup_controller_test.go
+++ b/test/integration/podgroup_controller_test.go
@@ -54,7 +54,7 @@ func TestPodGroupController(t *testing.T) {
 	testCtx.Ctx, testCtx.CancelFn = context.WithCancel(context.Background())
 
 	cs := kubernetes.NewForConfigOrDie(globalKubeConfig)
-	extClient := util.NewClientOrDie(globalKubeConfig)
+	extClient := util.NewClientOrDie(testCtx.Ctx, globalKubeConfig)
 	testCtx.ClientSet = cs
 	testCtx.KubeConfig = globalKubeConfig
 
diff --git a/test/integration/sysched_test.go b/test/integration/sysched_test.go
index 637829d4..b6325e3e 100644
--- a/test/integration/sysched_test.go
+++ b/test/integration/sysched_test.go
@@ -34,10 +34,10 @@ import (
 	fwkruntime "k8s.io/kubernetes/pkg/scheduler/framework/runtime"
 	st "k8s.io/kubernetes/pkg/scheduler/testing"
 	imageutils "k8s.io/kubernetes/test/utils/image"
-	"sigs.k8s.io/controller-runtime/pkg/client"
 	schedconfig "sigs.k8s.io/scheduler-plugins/apis/config"
 	"sigs.k8s.io/scheduler-plugins/apis/scheduling/v1alpha1"
 	"sigs.k8s.io/scheduler-plugins/pkg/sysched"
+	clientutil "sigs.k8s.io/scheduler-plugins/pkg/util"
 	"sigs.k8s.io/scheduler-plugins/test/util"
 	spo "sigs.k8s.io/security-profiles-operator/api/seccompprofile/v1beta1"
 )
@@ -136,7 +136,7 @@ func TestSyschedPlugin(t *testing.T) {
 	_ = v1alpha1.AddToScheme(scheme)
 	_ = spo.AddToScheme(scheme)
 
-	extClient, err := client.New(globalKubeConfig, client.Options{Scheme: scheme})
+	extClient, _, err := clientutil.NewClientWithCachedReader(testCtx.Ctx, globalKubeConfig, scheme)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -204,7 +204,7 @@ func TestSyschedPlugin(t *testing.T) {
 	for i := 0; i < 2; i++ {
 		nodeName := fmt.Sprintf("fake-node-%d", i)
 		node := st.MakeNode().Name(nodeName).Label("node", nodeName).Obj()
-		//node.Spec.PodCIDR = "192.168.0.1/24"
+		// node.Spec.PodCIDR = "192.168.0.1/24"
 		node.Status.Addresses = make([]v1.NodeAddress, 1)
 		ip := fmt.Sprintf("192.168.1.%v", 1+i)
 		node.Status.Addresses[0] = v1.NodeAddress{
diff --git a/test/integration/topologicalsort_test.go b/test/integration/topologicalsort_test.go
index 762edfc4..4f1d4c6c 100644
--- a/test/integration/topologicalsort_test.go
+++ b/test/integration/topologicalsort_test.go
@@ -39,11 +39,10 @@ import (
 	st "k8s.io/kubernetes/pkg/scheduler/testing"
 	imageutils "k8s.io/kubernetes/test/utils/image"
 
-	ctrlclient "sigs.k8s.io/controller-runtime/pkg/client"
-
 	scheconfig "sigs.k8s.io/scheduler-plugins/apis/config"
 	"sigs.k8s.io/scheduler-plugins/pkg/networkaware/topologicalsort"
 	networkawareutil "sigs.k8s.io/scheduler-plugins/pkg/networkaware/util"
+	clientutil "sigs.k8s.io/scheduler-plugins/pkg/util"
 	"sigs.k8s.io/scheduler-plugins/test/util"
 
 	appgroupapi "github.com/diktyo-io/appgroup-api/pkg/apis/appgroup"
@@ -58,7 +57,7 @@ func TestTopologicalSortPlugin(t *testing.T) {
 	utilruntime.Must(clientgoscheme.AddToScheme(scheme))
 	utilruntime.Must(agv1alpha1.AddToScheme(scheme))
 
-	client, err := ctrlclient.New(globalKubeConfig, ctrlclient.Options{Scheme: scheme})
+	client, _, err := clientutil.NewClientWithCachedReader(testCtx.Ctx, globalKubeConfig, scheme)
 
 	cs := kubernetes.NewForConfigOrDie(globalKubeConfig)
 	testCtx.ClientSet = cs
diff --git a/test/util/fake.go b/test/util/fake.go
index 7ed0c10e..4af49981 100644
--- a/test/util/fake.go
+++ b/test/util/fake.go
@@ -17,6 +17,7 @@ limitations under the License.
 package util
 
 import (
+	"context"
 	"sync"
 
 	v1 "k8s.io/api/core/v1"
@@ -30,6 +31,7 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/client/fake"
 	"sigs.k8s.io/scheduler-plugins/apis/scheduling/v1alpha1"
+	"sigs.k8s.io/scheduler-plugins/pkg/util"
 
 	topologyv1alpha2 "github.com/k8stopologyawareschedwg/noderesourcetopology-api/pkg/apis/topology/v1alpha2"
 )
@@ -290,13 +292,13 @@ func NewFakeClient(objs ...runtime.Object) (client.WithWatch, error) {
 
 // NewClientOrDie returns a generic controller-runtime client or panic upon any error.
 // This function is used by integration tests.
-func NewClientOrDie(cfg *rest.Config) client.Client {
+func NewClientOrDie(ctx context.Context, cfg *rest.Config) client.Client {
 	scheme := runtime.NewScheme()
 	_ = clientscheme.AddToScheme(scheme)
 	_ = v1.AddToScheme(scheme)
 	_ = v1alpha1.AddToScheme(scheme)
 
-	c, err := client.New(cfg, client.Options{Scheme: scheme})
+	c, _, err := util.NewClientWithCachedReader(ctx, cfg, scheme)
 	if err != nil {
 		panic(err)
 	}