Repository: kubernetes-sigs/kueue

Issue:
DRY API Documentation
**What would you like to be cleaned**:
We should reuse documentation in the API, by defining comments on the types, not fields of a type. At least when multiple fields reuse the same type in the exact same manner.

See https://github.com/kubernetes-sigs/kueue/pull/4165#issuecomment-2701009798

**Why is this needed**:

Hints from issue comments:
@k8s-triage-robot: The Kubernetes project currently lacks enough contributors to adequately respond to all issues.

This bot triages un-triaged issues according to the following rules:
- After 90d of inactivity, `lifecycle/stale` is applied
- After 30d of inactivity since `lifecycle/stale` was applied, `lifecycle/rotten` is applied
- After 30d of inactivity since `lifecycle/rotten` was applied, the issue is closed

You can:
- Mark this issue as fresh with `/remove-lifecycle stale`
- Close this issue with `/close`
- Offer to help out with [Issue Triage][1]

Please send feedback to sig-contributor-experience at [kubernetes/community](https://github.com/kubernetes/community).

/lifecycle stale

[1]: https://www.kubernetes.dev/docs/guide/issue-triage/@k8s-triage-robot: The Kubernetes project currently lacks enough active contributors to adequately respond to all issues.

This bot triages un-triaged issues according to the following rules:
- After 90d of inactivity, `lifecycle/stale` is applied
- After 30d of inactivity since `lifecycle/stale` was applied, `lifecycle/rotten` is applied
- After 30d of inactivity since `lifecycle/rotten` was applied, the issue is closed

You can:
- Mark this issue as fresh with `/remove-lifecycle rotten`
- Close this issue with `/close`
- Offer to help out with [Issue Triage][1]

Please send feedback to sig-contributor-experience at [kubernetes/community](https://github.com/kubernetes/community).

/lifecycle rotten

[1]: https://www.kubernetes.dev/docs/guide/issue-triage/@k8s-triage-robot: The Kubernetes project currently lacks enough active contributors to adequately respond to all issues and PRs.

This bot triages issues according to the following rules:
- After 90d of inactivity, `lifecycle/stale` is applied
- After 30d of inactivity since `lifecycle/stale` was applied, `lifecycle/rotten` is applied
- After 30d of inactivity since `lifecycle/rotten` was applied, the issue is closed

You can:
- Reopen this issue with `/reopen`
- Mark this issue as fresh with `/remove-lifecycle rotten`
- Offer to help out with [Issue Triage][1]

Please send feedback to sig-contributor-experience at [kubernetes/community](https://github.com/kubernetes/community).

/close not-planned

[1]: https://www.kubernetes.dev/docs/guide/issue-triage/@k8s-ci-robot: @k8s-triage-robot: Closing this issue, marking it as "Not Planned".

<details>

In response to [this](https://github.com/kubernetes-sigs/kueue/issues/4612#issuecomment-3174956029):

>The Kubernetes project currently lacks enough active contributors to adequately respond to all issues and PRs.
>
>This bot triages issues according to the following rules:
>- After 90d of inactivity, `lifecycle/stale` is applied
>- After 30d of inactivity since `lifecycle/stale` was applied, `lifecycle/rotten` is applied
>- After 30d of inactivity since `lifecycle/rotten` was applied, the issue is closed
>
>You can:
>- Reopen this issue with `/reopen`
>- Mark this issue as fresh with `/remove-lifecycle rotten`
>- Offer to help out with [Issue Triage][1]
>
>Please send feedback to sig-contributor-experience at [kubernetes/community](https://github.com/kubernetes/community).
>
>/close not-planned
>
>[1]: https://www.kubernetes.dev/docs/guide/issue-triage/


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.
</details>

Solution patch:
diff --git a/.github/ISSUE_TEMPLATE/NEW_RELEASE.md b/.github/ISSUE_TEMPLATE/NEW_RELEASE.md
index 5d65a0684..4edb95cde 100644
--- a/.github/ISSUE_TEMPLATE/NEW_RELEASE.md
+++ b/.github/ISSUE_TEMPLATE/NEW_RELEASE.md
@@ -19,7 +19,7 @@ Please do not remove items from the checklist
   - [ ] An OWNER creates a vanilla release branch with
         `git branch release-$MAJ.$MIN main`
   - [ ] An OWNER pushes the new release branch with
-        `git push release-$MAJ.$MIN`
+        `git push upstream release-$MAJ.$MIN`
 - [ ] Update the release branch:
   - [ ] Update `RELEASE_BRANCH` and `RELEASE_VERSION` in `Makefile` and run `make prepare-release-branch`
   - [ ] Update the `CHANGELOG`
@@ -39,12 +39,11 @@ Please do not remove items from the checklist
       `make artifacts IMAGE_REGISTRY=registry.k8s.io/kueue GIT_TAG=$VERSION`
       to generate the artifacts in the `artifacts` folder.
   - [ ] Upload the files in the `artifacts` folder to the draft release - either
-      via UI or `gh release --repo kubernetes-sigs/kueue upload <tag> artifacts/*`.
-- [ ] Submit a PR against [k8s.io](https://github.com/kubernetes/k8s.io) to 
+      via UI or `gh release --repo kubernetes-sigs/kueue upload $VERSION artifacts/*`.
+- [ ] Submit a PR against [k8s.io](https://github.com/kubernetes/k8s.io) to
       [promote the container images and Helm Chart](https://github.com/kubernetes/k8s.io/tree/main/registry.k8s.io#image-promoter)
-      to production: <!-- example kubernetes/k8s.io#3612 and kubernetes/k8s.io#7817 -->
+      to production: <!-- example kubernetes/k8s.io#7899 -->
   - [ ] Update `registry.k8s.io/images/k8s-staging-kueue/images.yaml`.
-  - [ ] Update `registry.k8s.io/images/charts/images.yaml`.
 - [ ] Wait for the PR to be merged and verify that the image `registry.k8s.io/kueue/kueue:$VERSION` is available.
 - [ ] Publish the draft release prepared at the [GitHub releases page](https://github.com/kubernetes-sigs/kueue/releases).
       Link: <!-- example https://github.com/kubernetes-sigs/kueue/releases/tag/v0.1.0 -->
@@ -62,13 +61,14 @@ Please do not remove items from the checklist
   - [ ] Create an unannotated _devel_ tag in the
         `main` branch, on the first commit that gets merged after the release
          branch has been created (presumably the README update commit above), and, push the tag:
-        `DEVEL=v$MAJ.$(($MIN+1)).0-devel; git tag $DEVEL main && git push $DEVEL`
+        `DEVEL=v$MAJ.$(($MIN+1)).0-devel; git tag $DEVEL main && git push upstream $DEVEL`
         This ensures that the devel builds on the `main` branch will have a meaningful version number.
   - [ ] Create a milestone for the next minor release and update prow to set it automatically for new PRs:
         <!-- example https://github.com/kubernetes/test-infra/pull/30222 -->
   - [ ] Create the presubmits and the periodic jobs for the next patch release:
-        <!-- example presubmit: https://github.com/kubernetes/test-infra/pull/33107 -->
-        <!-- example periodic: https://github.com/kubernetes/test-infra/pull/33833 -->
+        <!-- example: https://github.com/kubernetes/test-infra/pull/34561 -->
+  - [ ] Drop CI Jobs for testing the out-of-support branch:
+        <!-- example: https://github.com/kubernetes/test-infra/pull/34562 -->
 
 
 ## Changelog
diff --git a/.gitignore b/.gitignore
index c20e0f25b..b8fa17518 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,3 +31,4 @@ testbin/*
 dep-crds
 
 kueue.yaml
+node_modules
diff --git a/CHANGELOG/CHANGELOG-0.11.md b/CHANGELOG/CHANGELOG-0.11.md
new file mode 100644
index 000000000..735d729e0
--- /dev/null
+++ b/CHANGELOG/CHANGELOG-0.11.md
@@ -0,0 +1,114 @@
+## v0.11.1
+
+Changes since `v0.11.0`:
+
+## Changes by Kind
+
+### Bug or Regression
+
+- Add Necessary RBAC to Update Cohort Status (#4723, @gabesaba)
+- Fixed bug that doesn't allow to use WorkloadPriorityClass on LeaderWorkerSet. (#4725, @mbobrovskyi)
+
+## v0.11.0
+
+Changes since `0.10.0`:
+
+## Urgent Upgrade Notes
+
+### (No, really, you MUST read this before you upgrade)
+
+- If you implement the GenericJob interface for a custom Job CRD you need to update the
+  implementation of the PodSets function as its signature is extended to return potential errors. (#4002, @Horiodino)
+ - If you implement the GenericJob interface you need to update the implementation as
+  the PodSet.Name field has changed its type from string to PodSetReference. (#4417, @vladikkuzn)
+ - The configuration field `integrations.podOptions` is deprecated.
+
+  Users who set the `Integrations.PodOptions` namespace selector to a non-default
+  value should plan for migrating to use `managedJobsNamespaceSelector` instead, as the PodOptions
+  selector is going to be removed in a future release. (#4256, @dgrove-oss)
+
+## Changes by Kind
+
+### Feature
+
+- Add a column to multikueue indicating if it is connected to worker cluster (#4335, @highpon)
+- Add an integration for AppWrappers to Kueue. (#3953, @dgrove-oss)
+- Add integration for LeaderWorkerSet where Pods are managed by the pod-group integration. (#3515, @vladikkuzn)
+- Add the full name of the preempting workload to applicable log lines to make debugging preemption easier. (#4398, @KPostOffice)
+- Adds kueue-viz helm charts allowing installation of kueue-viz using helm (#3852, @akram)
+- Adds the JobUID to preemption condition messages.  This makes it easy to get the preempting workload using `kubectl get workloads --selector=kueue.x-k8s.io/job-uid=<JobUID>` (#4524, @avrittrohwer)
+- Allow mutating queue-name label in StatefulSet Webhook when ReadyReplicas equals zero. (#3520, @mbobrovskyi)
+- Allow one to configure certificates for metrics (#4385, @kannon92)
+- Expose the TopologyName in LocalQueue status (#4543, @mbobrovskyi)
+- Helm: Adds kueueViz parameters `enableKueueViz`, `kueueViz.backend.image` and `kueueViz.frontend.image` (#4410, @akram)
+- Improve error messages when the ProvisioningRequest Admission Check is not initialized due to a missing or unsupported version of the ProvisioningRequest CRD. (#4131, @Horiodino)
+- Kueue exposes a new recovery mechanism as part of the WaitForPodsReady API. This evicts jobs which surpasses configured threshold for pod's recovery during runtime (#4301, @PBundyra)
+- Kueue exposes a new recovery mechanism as part of the WaitForPodsReady API. This evicts jobs which surpasses configured threshold for pod's recovery during runtime (#4302, @PBundyra)
+- Kueue-viz: allow to configure the application port by the KUEUE_VIZ_PORT env. variable. (#4178, @lekaf974)
+- MultiKueue: Add support for Kubeflow Training-Operator Jobs  `spec.runPolicy.managedBy` field (#4116, @mszadkow)
+- Support KubeRay integrations (RayJob and RayCluster) for MultiKueue via the managedBy mechanism.
+  This allows for the installation of the Ray operator on the management cluster. (#4677, @mszadkow)
+- Support Pod integration in MultiKueue. (#4034, @Bobbins228)
+- Support RayCluster in MultiKueue, assuming only Ray CRDs are installed on the management cluster. (#3959, @mszadkow)
+- Support RayJob in MultiKueue, assuming only Ray CRDs are installed on the management cluster. (#3892, @mszadkow)
+- TAS: Add a new default algorithm to minimize resource fragmentation. The old algorithm is gated behind the `TASLargestFit` feature gate. (#4228, @PBundyra)
+- TAS: Support cohorts and preemption within them. (#4418, @mimowo)
+- TAS: Support preemption within ClusterQueue (#4171, @mimowo)
+- TopologyAwareScheduling can now be used with `kueue.x-k8s.io/podset-unconstrained-topology` annotation (#4567, @PBundyra)
+- TopologyAwareScheduling can now be used with profiles based on feature gates. TopologyAwareScheduling has now a new algorithm LeastFreeCapacityFit (#4576, @PBundyra)
+- Upgrade Kuberay to v1.3.1. (#4568, @mszadkow)
+- Use TAS for workloads implicitly (without TAS annotations) when the target CQ is TAS-only, meaning
+  all the resource flavors have spec.topologyName specified. (#4519, @mimowo)
+- WaitForPodsReady countdown is now measured since the admission of the workload instead of setting `PodsReady` condition to `False` (#4287, @PBundyra)
+- [FSxHC] Add Cohort Fair Sharing Status and Metrics (#4561, @mbobrovskyi)
+- [FSxHC] Extend Cohort API with Fair Sharing Configuration (#4288, @gabesaba)
+- [FSxHC] Make Fair Sharing compatible with Hierarchical Cohorts during preemption (#4572, @gabesaba)
+- [FSxHC] Make Fair Sharing compatible with Hierarchical Cohorts during scheduling (#4503, @gabesaba)
+
+### Bug or Regression
+
+- Add missing external types to apply configurations (#4191, @astefanutti)
+- Align default value for `managedJobsNamespaceSelector` in helm chart and kustomize files. (#4262, @dgrove-oss)
+- Disable the StatefulSet webhook in the kube-system and kueue-system namespaces by default.
+  This aligns the default StatefulSet webhook configuration with the Pod and Deployment configurations. (#4121, @kannon92)
+- Fix a bug is incorrect field path in inadmissible reasons and messages when Pod resources requests do not satisfy LimitRange constraints. (#4267, @tenzen-y)
+- Fix a bug is incorrect field path in inadmissible reasons and messages when container requests exceed limits (#4216, @tenzen-y)
+- Fix a bug that allowed unsupported changes to some PodSpec fields which were resulting in the StatefulSet getting stuck on Pods with schedulingGates.
+
+  The validation blocks mutating the following Pod spec fields: `nodeSelector`, `affinity`, `tolerations`, `runtimeClassName`, `priority`, `topologySpreadConstraints`, `overhead`, `resourceClaims`, plus container (and init container) fields: `ports` and `resources.requests`.
+
+  Mutating other fields, such as container image, command or args, remains allowed and supported. (#4081, @mbobrovskyi)
+- Fix a bug that doesn't allow Kueue to delete Pods after a StatefulSet is deleted. (#4150, @mbobrovskyi)
+- Fix a bug that occurs when a PodTemplate has not been created yet, but the Cluster Autoscaler attempts to process the ProvisioningRequest and marks it as failed. (#4086, @mbobrovskyi)
+- Fix a bug that prevented tracking some of the controller-runtime metrics in Prometheus. (#4217, @tenzen-y)
+- Fix a bug truncating AdmissionCheck condition message at `1024` characters when creation of the associated ProvisioningRequest or PodTemplate fails.
+  Instead, use the `32*1024` characters limit as for condition messages. (#4190, @mbobrovskyi)
+- Fix building TAS assignments for workloads with multiple PodSets (eg. JobSet or kubeflow Jobs). The assignment was computed independently for the PodSets which could result in conflicts rendering the pods unschedulable by the kube-scheduler. (#3937, @kerthcet)
+- Fix populating the LocalQueue metrics: `kueue_local_queue_resource_usage` and `kueue_local_queue_resource_reservation`. (#3988, @mykysha)
+- Fix the bug that prevented Kueue from updating the AdmissionCheck state in the Workload status on a ProvisioningRequest creation error. (#4114, @mbobrovskyi)
+- Fix the bug that prevented scaling StatefulSets which aren't managed by Kueue when the "statefulset" integration is enabled. (#3991, @mbobrovskyi)
+- Fix the permission bug which prevented adding the `kueue.x-k8s.io/resource-in-use` finalizer to the Topology objects, resulting in repeatedly logged errors. (#3910, @kerthcet)
+- Fixes a bug in 0.10.0 which resulted in the kueue manager configuration not being logged. (#3876, @dgrove-oss)
+- Fixes a bug that would result in default values not being properly set on creation for enabled integrations whose API was not available when the Kueue controller started. (#4547, @dgrove-oss)
+- Helm: Fix the unspecified LeaderElection Role and Rolebinding namespaces (#4383, @eric-higgins-ai)
+- Helm: Fixed a bug that prometheus namespace is enforced with namespace the same as kueue-controller-manager (#4484, @kannon92)
+- Improve error message in the event when scheduling for TAS workload fails due to unassigned flavors. (#4204, @mimowo)
+- Propagate the top-level setting of the `kueue.x-k8s.io/priority-class` label to the PodTemplate for
+  Deployments and StatefulSets. This way the Workload Priority class is no longer ignored by the workloads. (#3980, @Abirdcfly)
+- TAS: Do not ignore the TAS annotation if set on the template for the Ray submitter Job. (#4341, @mszadkow)
+- TAS: Fix a bug that TopolologyUngator cound not be triggered the leader change when enabled HA mode (#4653, @tenzen-y)
+- TAS: Fix a bug that incorrect topologies are assigned to Workloads when topology has insufficient allocatable Pods count (#4271, @tenzen-y)
+- TAS: Fix a bug that unschedulable nodes (".spec.unschedulable=true") are counted as allocatable capacities (#4181, @tenzen-y)
+- TAS: Fixed a bug that allows to create a JobSet with both kueue.x-k8s.io/podset-required-topology and kueue.x-k8s.io/podset-preferred-topology annotations set on the PodTemplate. (#4130, @mbobrovskyi)
+- Update FairSharing to be incompatible with ClusterQueue.Preemption.BorrowWithinCohort. Using these parameters together is a no-op, and will be validated against in future releases. This change fixes an edge case which triggered an infinite preemption loop when these two parameters were combined. (#4165, @gabesaba)
+
+### Other (Cleanup or Flake)
+
+- MultiKueue: Do not update the status of the Job on the management cluster while the Job is suspended. This is updated  for jobs represented by JobSet, Kubeflow Jobs and MPIJob. (#4070, @IrvingMg)
+- Promote WorkloadResourceRequestsSummary feature gate to stable (#4166, @dgrove-oss)
+- Publish helm charts to the Kueue staging repository `http://us-central1-docker.pkg.dev/k8s-staging-images/kueue/charts`,
+  so that they can be promoted to the permanent location under `registry.k8s.io/kueue/charts`. (#4680, @mimowo)
+- Remove the support for Kubeflow MXJob. (#4077, @mszadkow)
+- Renamed Log key from "attemptCount" to "schedulingCycleCount". This key tracks how many scheduling cycles we have done since starting Kueue. (#4108, @gabesaba)
+- Support for Kubernetes 1.32 (#3820, @mbobrovskyi)
+- The APF configuration, using v1beta3 API dedicated for Kubernetes 1.28 (or older), for the visibility server is no longer part of the release artifacts of Kueue. (#3983, @mbobrovskyi)
diff --git a/Makefile b/Makefile
index f7aa8f138..02fa46fba 100644
--- a/Makefile
+++ b/Makefile
@@ -77,7 +77,7 @@ LD_FLAGS += -X '$(version_pkg).GitCommit=$(shell git rev-parse HEAD)'
 
 # Update these variables when preparing a new release or a release branch.
 # Then run `make prepare-release-branch`
-RELEASE_VERSION=v0.10.3
+RELEASE_VERSION=v0.11.1
 RELEASE_BRANCH=main
 # Version used form Helm which is not using the leading "v"
 CHART_VERSION := $(shell echo $(RELEASE_VERSION) | cut -c2-)
@@ -281,10 +281,10 @@ artifacts: kustomize yq helm ## Generate release artifacts.
 
 .PHONY: prepare-release-branch
 prepare-release-branch: yq kustomize ## Prepare the release branch with the release version.
-	$(SED) -r 's/version = "v[0-9]+\.[0-9]+\.[0-9]+/version = "$(RELEASE_VERSION)/g' -i README.md -i site/hugo.toml
+	$(SED) -r 's/v[0-9]+\.[0-9]+\.[0-9]+/$(RELEASE_VERSION)/g' -i README.md -i site/hugo.toml
 	$(SED) -r 's/chart_version = "[0-9]+\.[0-9]+\.[0-9]+/chart_version = "$(CHART_VERSION)/g' -i README.md -i site/hugo.toml
 	$(SED) -r 's/--version="v?[0-9]+\.[0-9]+\.[0-9]+/--version="$(CHART_VERSION)/g' -i charts/kueue/README.md
-	$(YQ) e '.appVersion = "$(CHART_VERSION)"' -i charts/kueue/Chart.yaml
+	$(YQ) e '.appVersion = "$(RELEASE_VERSION)"' -i charts/kueue/Chart.yaml
 	@$(call clean-manifests)
 
 .PHONY: update-security-insights
@@ -341,7 +341,7 @@ importer-image: importer-image-build
 kueue-viz-image-build:
 	$(IMAGE_BUILD_CMD) \
 		-t $(IMAGE_REGISTRY)/kueue-viz-backend:$(GIT_TAG) \
-		-t $(IMAGE_REGISTRY)/kueue-viz-backend:$(RELEASE_BRANCH)-latest \
+		-t $(IMAGE_REGISTRY)/kueue-viz-backend:$(RELEASE_BRANCH) \
 		--platform=$(VIZ_PLATFORMS) \
 		--build-arg BASE_IMAGE=$(BASE_IMAGE) \
 		--build-arg BUILDER_IMAGE=$(BUILDER_IMAGE) \
@@ -350,7 +350,7 @@ kueue-viz-image-build:
 		-f ./cmd/experimental/kueue-viz/backend/Dockerfile ./cmd/experimental/kueue-viz/backend; \
 	$(IMAGE_BUILD_CMD) \
 		-t $(IMAGE_REGISTRY)/kueue-viz-frontend:$(GIT_TAG) \
-		-t $(IMAGE_REGISTRY)/kueue-viz-frontend:$(RELEASE_BRANCH)-latest \
+		-t $(IMAGE_REGISTRY)/kueue-viz-frontend:$(RELEASE_BRANCH) \
 		--platform=$(VIZ_PLATFORMS) \
 		$(PUSH) \
 		-f ./cmd/experimental/kueue-viz/frontend/Dockerfile ./cmd/experimental/kueue-viz/frontend; \
diff --git a/Makefile-test.mk b/Makefile-test.mk
index 24ccd13ff..9ddf32638 100644
--- a/Makefile-test.mk
+++ b/Makefile-test.mk
@@ -69,6 +69,7 @@ IMAGE_REGISTRY ?= $(STAGING_IMAGE_REGISTRY)/kueue
 IMAGE_NAME := kueue
 IMAGE_REPO ?= $(IMAGE_REGISTRY)/$(IMAGE_NAME)
 IMAGE_TAG ?= $(IMAGE_REPO):$(GIT_TAG)
+CYPRESS_IMAGE_NAME ?= cypress/base:22.14.0
 
 # Versions for external controllers
 APPWRAPPER_VERSION = $(shell $(GO_CMD) list -m -f "{{.Version}}" github.com/project-codeflare/appwrapper)
@@ -257,3 +258,19 @@ ginkgo-top:
 	cd $(PROJECT_DIR)/hack/internal/tools && \
 	go mod download && \
 	$(GO_BUILD_ENV) $(GO_CMD) build -ldflags="$(LD_FLAGS)" -o $(PROJECT_DIR)/bin/ginkgo-top ./ginkgo-top
+
+.PHONY: setup-e2e-env
+setup-e2e-env: kustomize yq gomod-download dep-crds kueuectl kind ## Setup environment for e2e tests without running tests.
+	@echo "Setting up environment for e2e tests"
+
+.PHONY: test-e2e-kueueviz-local
+test-e2e-kueueviz-local: setup-e2e-env ## Run end-to-end tests for kueue-viz without running kueue tests.
+	ARTIFACTS=$(ARTIFACTS) KIND_CLUSTER_NAME=$(KIND_CLUSTER_NAME) \
+	KIND_CLUSTER_FILE="kind-cluster-viz.yaml" ${PROJECT_DIR}/hack/e2e-kueueviz-local.sh
+
+.PHONY: test-e2e-kueueviz
+test-e2e-kueueviz: setup-e2e-env ## Run end-to-end tests for kueue-viz without running kueue tests.
+	@echo Starting kueue-viz end to end test in containers
+	ARTIFACTS=$(ARTIFACTS) KIND_CLUSTER_NAME=$(KIND_CLUSTER_NAME) \
+	KIND_CLUSTER_FILE="kind-cluster-viz.yaml" \
+	CYPRESS_IMAGE_NAME=$(CYPRESS_IMAGE_NAME) ${PROJECT_DIR}/hack/e2e-kueueviz-backend.sh
diff --git a/README.md b/README.md
index ac881630f..9d4d64b0f 100644
--- a/README.md
+++ b/README.md
@@ -58,7 +58,7 @@ Read the [overview](https://kueue.sigs.k8s.io/docs/overview/) and watch the Kueu
 To install the latest release of Kueue in your cluster, run the following command:
 
 ```shell
-kubectl apply --server-side -f https://github.com/kubernetes-sigs/kueue/releases/download/v0.10.3/manifests.yaml
+kubectl apply --server-side -f https://github.com/kubernetes-sigs/kueue/releases/download/v0.11.1/manifests.yaml
 ```
 
 The controller runs in the `kueue-system` namespace.
diff --git a/SECURITY-INSIGHTS.yaml b/SECURITY-INSIGHTS.yaml
index a94c3d2b1..0732ad939 100644
--- a/SECURITY-INSIGHTS.yaml
+++ b/SECURITY-INSIGHTS.yaml
@@ -1,11 +1,11 @@
 header:
   schema-version: 1.0.0
   expiration-date: '2024-09-28T01:00:00.000Z'
-  last-updated: '2025-03-19'
-  last-reviewed: '2025-03-19'
-  commit-hash: c79419eb5b3b0021621805a73bec2ff58c398d8b
+  last-updated: '2025-03-20'
+  last-reviewed: '2025-03-20'
+  commit-hash: a42f482f88e283b68f7212f0f21d1b734ed0621c
   project-url: 'https://github.com/kubernetes-sigs/kueue'
-  project-release: 0.10.3
+  project-release: 0.11.1
   changelog: 'https://github.com/kubernetes-sigs/kueue/tree/main/CHANGELOG'
   license: 'https://github.com/kubernetes-sigs/kueue/blob/main/LICENSE'
 project-lifecycle:
@@ -28,7 +28,7 @@ documentation:
   - 'https://kueue.sigs.k8s.io/docs/'
 distribution-points:
   - >-
-    https://github.com/kubernetes-sigs/kueue/releases/download/v0.10.3/manifests.yaml
+    https://github.com/kubernetes-sigs/kueue/releases/download/v0.11.1/manifests.yaml
 security-artifacts:
   threat-model:
     threat-model-created: false
@@ -62,5 +62,5 @@ dependencies:
   dependencies-lists:
     - 'https://github.com/kubernetes-sigs/kueue/blob/main/go.mod'
   sbom:
-    - sbom-file: https://github.com/kubernetes-sigs/kueue/releases/download/v0.10.3/kueue-v0.10.3.spdx.json
+    - sbom-file: https://github.com/kubernetes-sigs/kueue/releases/download/v0.11.1/kueue-v0.11.1.spdx.json
       sbom-format: SPDX
diff --git a/apis/kueue/v1alpha1/cohort_types.go b/apis/kueue/v1alpha1/cohort_types.go
index 9fa00723d..778c06e93 100644
--- a/apis/kueue/v1alpha1/cohort_types.go
+++ b/apis/kueue/v1alpha1/cohort_types.go
@@ -64,7 +64,11 @@ type CohortSpec struct {
 	FairSharing *kueuebeta.FairSharing `json:"fairSharing,omitempty"`
 }
 
+// CohortStatus defines the observed state of Cohort.
 type CohortStatus struct {
+	// fairSharing contains the current state for this Cohort
+	// when participating in Fair Sharing.
+	// The is recorded only when Fair Sharing is enabled in the Kueue configuration.
 	// +optional
 	FairSharing *kueuebeta.FairSharingStatus `json:"fairSharing,omitempty"`
 }
diff --git a/apis/kueue/v1beta1/clusterqueue_types.go b/apis/kueue/v1beta1/clusterqueue_types.go
index 478b70737..bbf05c93a 100644
--- a/apis/kueue/v1beta1/clusterqueue_types.go
+++ b/apis/kueue/v1beta1/clusterqueue_types.go
@@ -302,6 +302,9 @@ type ClusterQueueStatus struct {
 	// +optional
 	PendingWorkloadsStatus *ClusterQueuePendingWorkloadsStatus `json:"pendingWorkloadsStatus"`
 
+	// fairSharing contains the current state for this ClusterQueue
+	// when participating in Fair Sharing.
+	// This is recorded only when Fair Sharing is enabled in the Kueue configuration.
 	// +optional
 	FairSharing *FairSharingStatus `json:"fairSharing,omitempty"`
 }
diff --git a/apis/kueue/v1beta1/fairsharing_types.go b/apis/kueue/v1beta1/fairsharing_types.go
index bb175d975..4c5e27867 100644
--- a/apis/kueue/v1beta1/fairsharing_types.go
+++ b/apis/kueue/v1beta1/fairsharing_types.go
@@ -39,9 +39,9 @@ type FairSharing struct {
 	Weight *resource.Quantity `json:"weight,omitempty"`
 }
 
-// fairSharing contains the information about the current status of Fair Sharing.
+// FairSharingStatus contains the information about the current status of Fair Sharing.
 type FairSharingStatus struct {
-	// WeightedShare represent the maximum of the ratios of usage
+	// WeightedShare represents the maximum of the ratios of usage
 	// above nominal quota to the lendable resources in the
 	// Cohort, among all the resources provided by the Node, and
 	// divided by the weight.  If zero, it means that the usage of
diff --git a/charts/kueue/Chart.yaml b/charts/kueue/Chart.yaml
index c650f7d01..6442e5eea 100644
--- a/charts/kueue/Chart.yaml
+++ b/charts/kueue/Chart.yaml
@@ -21,4 +21,4 @@ version: 0.1.0
 # incremented each time you make changes to the application. Versions are not expected to
 # follow Semantic Versioning. They should reflect the version the application is using.
 # It is recommended to use it with quotes.
-appVersion: "0.10.3"
+appVersion: "v0.11.1"
diff --git a/charts/kueue/README.md b/charts/kueue/README.md
index 580471030..159d25919 100644
--- a/charts/kueue/README.md
+++ b/charts/kueue/README.md
@@ -37,7 +37,7 @@ $ helm install kueue kueue/ --create-namespace --namespace kueue-system
 Or use the charts pushed to `us-central1-docker.pkg.dev/k8s-staging-images/kueue/charts/kueue`:
 
 ```bash
-helm install kueue oci://us-central1-docker.pkg.dev/k8s-staging-images/kueue/charts/kueue --version="0.10.3" --create-namespace --namespace=kueue-system
+helm install kueue oci://us-central1-docker.pkg.dev/k8s-staging-images/kueue/charts/kueue --version="0.11.1" --create-namespace --namespace=kueue-system
 ```
 
 ##### Verify that controller pods are running properly.
@@ -75,8 +75,8 @@ The following table lists the configurable parameters of the kueue chart and the
 | `enableCertManager`                                    | enable CertManager                                     | `false`                                     |
 | `enableVisibilityAPF`                                  | enable APF for the visibility API                      | `false`                                     |
 | `enableKueueViz`                                       | enable KueueViz dashboard                              | `false`                                     |
-| `kueueViz.backend.image`                               | KueueViz dashboard backend image                       | `us-central1-docker.pkg.dev/k8s-staging-images/kueue/kueue-viz-backend:main-latest` |
-| `kueueViz.frontend.image`                              | KueueViz dashboard frontend image                      | `us-central1-docker.pkg.dev/k8s-staging-images/kueue/kueue-viz-frontend:main-latest` |
+| `kueueViz.backend.image`                               | KueueViz dashboard backend image                       | `us-central1-docker.pkg.dev/k8s-staging-images/kueue/kueue-viz-backend:main` |
+| `kueueViz.frontend.image`                              | KueueViz dashboard frontend image                      | `us-central1-docker.pkg.dev/k8s-staging-images/kueue/kueue-viz-frontend:main` |
 | `controllerManager.manager.image.repository`           | controllerManager.manager's repository and image       | `us-central1-docker.pkg.dev/k8s-staging-images/kueue/kueue` |
 | `controllerManager.manager.image.tag`                  | controllerManager.manager's tag                        | `main`                                      |
 | `controllerManager.manager.resources`                  | controllerManager.manager's resources                  | abbr.                                       |
diff --git a/charts/kueue/templates/crd/kueue.x-k8s.io_clusterqueues.yaml b/charts/kueue/templates/crd/kueue.x-k8s.io_clusterqueues.yaml
index 50271b502..ff2f50b96 100644
--- a/charts/kueue/templates/crd/kueue.x-k8s.io_clusterqueues.yaml
+++ b/charts/kueue/templates/crd/kueue.x-k8s.io_clusterqueues.yaml
@@ -582,12 +582,14 @@ spec:
                 - type
                 x-kubernetes-list-type: map
               fairSharing:
-                description: fairSharing contains the information about the current
-                  status of Fair Sharing.
+                description: |-
+                  fairSharing contains the current state for this ClusterQueue
+                  when participating in Fair Sharing.
+                  This is recorded only when Fair Sharing is enabled in the Kueue configuration.
                 properties:
                   weightedShare:
                     description: |-
-                      WeightedShare represent the maximum of the ratios of usage
+                      WeightedShare represents the maximum of the ratios of usage
                       above nominal quota to the lendable resources in the
                       Cohort, among all the resources provided by the Node, and
                       divided by the weight.  If zero, it means that the usage of
diff --git a/charts/kueue/templates/crd/kueue.x-k8s.io_cohorts.yaml b/charts/kueue/templates/crd/kueue.x-k8s.io_cohorts.yaml
index 3619a48f8..aeb51946b 100644
--- a/charts/kueue/templates/crd/kueue.x-k8s.io_cohorts.yaml
+++ b/charts/kueue/templates/crd/kueue.x-k8s.io_cohorts.yaml
@@ -244,14 +244,17 @@ spec:
                 x-kubernetes-list-type: atomic
             type: object
           status:
+            description: CohortStatus defines the observed state of Cohort.
             properties:
               fairSharing:
-                description: fairSharing contains the information about the current
-                  status of Fair Sharing.
+                description: |-
+                  fairSharing contains the current state for this Cohort
+                  when participating in Fair Sharing.
+                  The is recorded only when Fair Sharing is enabled in the Kueue configuration.
                 properties:
                   weightedShare:
                     description: |-
-                      WeightedShare represent the maximum of the ratios of usage
+                      WeightedShare represents the maximum of the ratios of usage
                       above nominal quota to the lendable resources in the
                       Cohort, among all the resources provided by the Node, and
                       divided by the weight.  If zero, it means that the usage of
diff --git a/charts/kueue/templates/kueue-viz/backend-deployment.yaml b/charts/kueue/templates/kueue-viz/backend-deployment.yaml
index aa6dbe76d..a7f4766bb 100644
--- a/charts/kueue/templates/kueue-viz/backend-deployment.yaml
+++ b/charts/kueue/templates/kueue-viz/backend-deployment.yaml
@@ -16,7 +16,7 @@ spec:
     spec:
       containers:
         - name: backend
-          image: '{{ .Values.kueueViz.backend.image | default "us-central1-docker.pkg.dev/k8s-staging-images/kueue/kueue-viz-backend:main-latest" }}'
+          image: '{{ .Values.kueueViz.backend.image | default "us-central1-docker.pkg.dev/k8s-staging-images/kueue/kueue-viz-backend:main" }}'
           imagePullPolicy: IfNotPresent
           ports:
             - containerPort: 8080
diff --git a/charts/kueue/templates/kueue-viz/frontend-deployment.yaml b/charts/kueue/templates/kueue-viz/frontend-deployment.yaml
index 395e5ae9d..8e37a159e 100644
--- a/charts/kueue/templates/kueue-viz/frontend-deployment.yaml
+++ b/charts/kueue/templates/kueue-viz/frontend-deployment.yaml
@@ -16,7 +16,7 @@ spec:
     spec:
       containers:
         - name: frontend
-          image: '{{ .Values.kueueViz.frontend.image | default "us-central1-docker.pkg.dev/k8s-staging-images/kueue/kueue-viz-frontend:main-latest" }}'
+          image: '{{ .Values.kueueViz.frontend.image | default "us-central1-docker.pkg.dev/k8s-staging-images/kueue/kueue-viz-frontend:main" }}'
           imagePullPolicy: IfNotPresent
           ports:
             - containerPort: 8080
diff --git a/charts/kueue/templates/rbac/role.yaml b/charts/kueue/templates/rbac/role.yaml
index 14eab7282..947ebd37d 100644
--- a/charts/kueue/templates/rbac/role.yaml
+++ b/charts/kueue/templates/rbac/role.yaml
@@ -233,6 +233,7 @@ rules:
     resources:
       - admissionchecks/status
       - clusterqueues/status
+      - cohorts/status
       - localqueues/status
       - multikueueclusters/status
       - workloads/status
diff --git a/charts/kueue/values.yaml b/charts/kueue/values.yaml
index 18518abfc..8baeb5abc 100644
--- a/charts/kueue/values.yaml
+++ b/charts/kueue/values.yaml
@@ -153,9 +153,15 @@ webhookService:
 
 # kueue-viz dashboard
 enableKueueViz: false
+kueueViz:
+  backend:
+    image: "us-central1-docker.pkg.dev/k8s-staging-images/kueue/kueue-viz-backend:main"
+  frontend:
+    image: "us-central1-docker.pkg.dev/k8s-staging-images/kueue/kueue-viz-frontend:main"
 
 metrics:
   prometheusNamespace: monitoring
   serviceMonitor:
     tlsConfig:
       insecureSkipVerify: true
+
diff --git a/cmd/experimental/kueue-viz/frontend/.gitignore b/cmd/experimental/kueue-viz/frontend/.gitignore
index a8f60abbb..a60498a68 100644
--- a/cmd/experimental/kueue-viz/frontend/.gitignore
+++ b/cmd/experimental/kueue-viz/frontend/.gitignore
@@ -1,5 +1,6 @@
 node_modules/
 package-lock.json
 build/
+cypress/screenshots
 yarn.lock
 
diff --git a/cmd/experimental/kueue-viz/frontend/cypress.config.js b/cmd/experimental/kueue-viz/frontend/cypress.config.js
new file mode 100644
index 000000000..d19dea177
--- /dev/null
+++ b/cmd/experimental/kueue-viz/frontend/cypress.config.js
@@ -0,0 +1,16 @@
+import { defineConfig } from "cypress";
+
+export default defineConfig({
+  e2e: {
+    baseUrl: 'http://localhost:3000',
+    setupNodeEvents(on, config) {
+      // implement node event listeners here
+    },
+  },
+  component: {
+    devServer: {
+      framework: 'react',
+      bundler: 'vite',
+    },
+  },
+});
diff --git a/cmd/experimental/kueue-viz/frontend/cypress/e2e/app.cy.js b/cmd/experimental/kueue-viz/frontend/cypress/e2e/app.cy.js
new file mode 100644
index 000000000..a8741e39e
--- /dev/null
+++ b/cmd/experimental/kueue-viz/frontend/cypress/e2e/app.cy.js
@@ -0,0 +1,74 @@
+describe('Kueue Dashboard', () => {
+  beforeEach(() => {
+    cy.visit('/')
+  })
+
+  
+  it('should have the correct title', () => {
+    cy.title().should('contain', 'Kueue Dashboard')
+  })
+
+  it('should navigate to resource-flavors and verify table content', () => {
+    // Check for the link to resource-flavors
+    cy.get('a[href="/resource-flavors"]').should('exist')
+      .click()
+
+    // Verify the table structure and content
+    cy.get('table').should('exist')
+    cy.get('th').contains('Name')
+    cy.get('th').contains('Details')
+
+    // Check for specific row values
+    cy.get('td').contains('default-flavor')
+    cy.get('td').contains('gpu')
+    cy.get('td').contains('spot')
+  })
+
+  it('should navigate to cluster-queue and verify local queues', () => {
+    // Find and click the link to /cluster-queue/agi-cluster-queue
+    cy.get('a[href="/cluster-queue/agi-cluster-queue"]').should('exist')
+      .click()
+
+    // Verify the section and table
+    cy.contains('Local Queues Using This Cluster Queue').should('exist')
+    cy.get('th').contains('Queue Name')
+
+    // Navigate to the first link in the table
+    cy.get('table').find('a').first().click()
+  })
+
+  it('should verify cohort link and navigate to cohorts page', () => {
+    // Navigate to /cluster-queue/agi-cluster-queue
+    cy.visit('/cluster-queue/agi-cluster-queue')
+
+    // Verify the link to /cohort/ai-for-humanity-foundation
+    cy.get('a[href="/cohort/ai-for-humanity-foundation"]').should('exist')
+
+    // Navigate to /cohorts
+    cy.get('a[href="/cohorts"]').should('exist')
+      .click()
+
+    // Verify the table and its content
+    cy.get('table').should('exist')
+    cy.get('th').contains('Cluster Queue Name')
+    cy.get('td').contains('agi-cluster-queue')
+    cy.get('td').contains('emergency-cluster-queue')
+    cy.get('td').contains('llm-cluster-queue')
+  })
+
+  it('should verify the presence of all main links', () => {
+    const links = [
+      '/workloads',
+      '/local-queues',
+      '/cluster-queues',
+      '/cohorts',
+      '/resource-flavors'
+    ];
+
+    links.forEach(link => {
+      cy.get(`a[href="${link}"]`).should('exist').click();
+    });
+  })
+
+  // Add more test cases here as needed
+}) 
\ No newline at end of file
diff --git a/cmd/experimental/kueue-viz/frontend/cypress/support/commands.js b/cmd/experimental/kueue-viz/frontend/cypress/support/commands.js
new file mode 100644
index 000000000..66ea16ef0
--- /dev/null
+++ b/cmd/experimental/kueue-viz/frontend/cypress/support/commands.js
@@ -0,0 +1,25 @@
+// ***********************************************
+// This example commands.js shows you how to
+// create various custom commands and overwrite
+// existing commands.
+//
+// For more comprehensive examples of custom
+// commands please read more here:
+// https://on.cypress.io/custom-commands
+// ***********************************************
+//
+//
+// -- This is a parent command --
+// Cypress.Commands.add('login', (email, password) => { ... })
+//
+//
+// -- This is a child command --
+// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
+//
+//
+// -- This is a dual command --
+// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
+//
+//
+// -- This will overwrite an existing command --
+// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
\ No newline at end of file
diff --git a/cmd/experimental/kueue-viz/frontend/cypress/support/e2e.js b/cmd/experimental/kueue-viz/frontend/cypress/support/e2e.js
new file mode 100644
index 000000000..5fb7e6a6a
--- /dev/null
+++ b/cmd/experimental/kueue-viz/frontend/cypress/support/e2e.js
@@ -0,0 +1,23 @@
+// ***********************************************************
+// This example support/e2e.js is processed and
+// loaded automatically before your test files.
+//
+// This is a great place to put global configuration and
+// behavior that modifies Cypress.
+//
+// You can change the location of this file or turn off
+// automatically serving support files with the
+// 'supportFile' configuration option.
+//
+// You can read more here:
+// https://on.cypress.io/configuration
+// ***********************************************************
+
+// Import commands.js using ES2015 syntax:
+import './commands'
+
+// Import Testing Library commands
+import '@testing-library/cypress/add-commands'
+
+// Alternatively you can use CommonJS syntax:
+// require('./commands')
\ No newline at end of file
diff --git a/cmd/experimental/kueue-viz/frontend/package.json b/cmd/experimental/kueue-viz/frontend/package.json
index 4009d56df..7f1420cc9 100644
--- a/cmd/experimental/kueue-viz/frontend/package.json
+++ b/cmd/experimental/kueue-viz/frontend/package.json
@@ -8,8 +8,12 @@
   "scripts": {
     "start": "vite",
     "build": "vite build",
+    "dev": "vite --no-open",
     "preview": "vite preview",
-    "check-unused": "depcheck"
+    "check-unused": "depcheck",
+    "cypress:open": "cypress open",
+    "cypress:run": "cypress run",
+    "test:e2e": "start-server-and-test start http://localhost:3000 cypress:run"
   },
   "dependencies": {
     "@emotion/react": "^11.14.0",
@@ -23,9 +27,12 @@
     "react-toastify": "^11.0.5"
   },
   "devDependencies": {
+    "@testing-library/cypress": "^10.0.3",
     "@vitejs/plugin-react": "^4.3.4",
+    "cypress": "^14.1.0",
     "depcheck": "^1.4.7",
     "serve": "^14.2.4",
+    "start-server-and-test": "^2.0.10",
     "vite": "^6.2.1"
   },
   "browserslist": {
diff --git a/cmd/experimental/kueue-viz/frontend/src/ResourceFlavorDetail.jsx b/cmd/experimental/kueue-viz/frontend/src/ResourceFlavorDetail.jsx
index 1eefa0334..9ff2249d4 100644
--- a/cmd/experimental/kueue-viz/frontend/src/ResourceFlavorDetail.jsx
+++ b/cmd/experimental/kueue-viz/frontend/src/ResourceFlavorDetail.jsx
@@ -15,7 +15,7 @@ limitations under the License.
 */
 
 import React, { useState, useEffect } from 'react';
-import { useParams } from 'react-router-dom';
+import { useParams, Link } from 'react-router-dom';
 import { Typography, Paper, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, CircularProgress, Box } from '@mui/material';
 import useWebSocket from './useWebSocket';
 import './App.css';
@@ -111,7 +111,9 @@ const ResourceFlavorDetail = () => {
                 {queues?.map((queue) => (
                   <React.Fragment key={queue.queueName}>
                     <TableRow>
-                      <TableCell rowSpan={queue.quota.length}>{queue.queueName}</TableCell>
+                      <TableCell rowSpan={queue.quota.length}>
+                        <Link to={`/cluster-queue/${queue.queueName}`}>{queue.queueName}</Link>
+                      </TableCell>
                       <TableCell>{queue.quota[0].resource}</TableCell>
                       <TableCell>{queue.quota[0].nominalQuota}</TableCell>
                     </TableRow>
diff --git a/config/components/crd/bases/kueue.x-k8s.io_clusterqueues.yaml b/config/components/crd/bases/kueue.x-k8s.io_clusterqueues.yaml
index 962623045..f158cbe17 100644
--- a/config/components/crd/bases/kueue.x-k8s.io_clusterqueues.yaml
+++ b/config/components/crd/bases/kueue.x-k8s.io_clusterqueues.yaml
@@ -567,12 +567,14 @@ spec:
                 - type
                 x-kubernetes-list-type: map
               fairSharing:
-                description: fairSharing contains the information about the current
-                  status of Fair Sharing.
+                description: |-
+                  fairSharing contains the current state for this ClusterQueue
+                  when participating in Fair Sharing.
+                  This is recorded only when Fair Sharing is enabled in the Kueue configuration.
                 properties:
                   weightedShare:
                     description: |-
-                      WeightedShare represent the maximum of the ratios of usage
+                      WeightedShare represents the maximum of the ratios of usage
                       above nominal quota to the lendable resources in the
                       Cohort, among all the resources provided by the Node, and
                       divided by the weight.  If zero, it means that the usage of
diff --git a/config/components/crd/bases/kueue.x-k8s.io_cohorts.yaml b/config/components/crd/bases/kueue.x-k8s.io_cohorts.yaml
index d56c73ac0..07a29c2b8 100644
--- a/config/components/crd/bases/kueue.x-k8s.io_cohorts.yaml
+++ b/config/components/crd/bases/kueue.x-k8s.io_cohorts.yaml
@@ -229,14 +229,17 @@ spec:
                 x-kubernetes-list-type: atomic
             type: object
           status:
+            description: CohortStatus defines the observed state of Cohort.
             properties:
               fairSharing:
-                description: fairSharing contains the information about the current
-                  status of Fair Sharing.
+                description: |-
+                  fairSharing contains the current state for this Cohort
+                  when participating in Fair Sharing.
+                  The is recorded only when Fair Sharing is enabled in the Kueue configuration.
                 properties:
                   weightedShare:
                     description: |-
-                      WeightedShare represent the maximum of the ratios of usage
+                      WeightedShare represents the maximum of the ratios of usage
                       above nominal quota to the lendable resources in the
                       Cohort, among all the resources provided by the Node, and
                       divided by the weight.  If zero, it means that the usage of
diff --git a/config/components/kueue-viz/backend-deployment.yaml b/config/components/kueue-viz/backend-deployment.yaml
index 7782a9c7b..1fa4584d9 100644
--- a/config/components/kueue-viz/backend-deployment.yaml
+++ b/config/components/kueue-viz/backend-deployment.yaml
@@ -16,7 +16,7 @@ spec:
     spec:
       containers:
         - name: backend
-          image: us-central1-docker.pkg.dev/k8s-staging-images/kueue/kueue-viz-backend:main-latest
+          image: us-central1-docker.pkg.dev/k8s-staging-images/kueue/kueue-viz-backend:main
           imagePullPolicy: IfNotPresent
           ports:
             - containerPort: 8080
diff --git a/config/components/kueue-viz/frontend-deployment.yaml b/config/components/kueue-viz/frontend-deployment.yaml
index 909a6c9a1..eb76a2117 100644
--- a/config/components/kueue-viz/frontend-deployment.yaml
+++ b/config/components/kueue-viz/frontend-deployment.yaml
@@ -17,7 +17,7 @@ spec:
 
       containers:
         - name: frontend
-          image: us-central1-docker.pkg.dev/k8s-staging-images/kueue/kueue-viz-frontend:main-latest
+          image: us-central1-docker.pkg.dev/k8s-staging-images/kueue/kueue-viz-frontend:main
           imagePullPolicy: IfNotPresent
           ports:
             - containerPort: 8080
diff --git a/config/components/rbac/role.yaml b/config/components/rbac/role.yaml
index 800e3fb5e..8ca7211e8 100644
--- a/config/components/rbac/role.yaml
+++ b/config/components/rbac/role.yaml
@@ -232,6 +232,7 @@ rules:
   resources:
   - admissionchecks/status
   - clusterqueues/status
+  - cohorts/status
   - localqueues/status
   - multikueueclusters/status
   - workloads/status
diff --git a/go.mod b/go.mod
index c5a9a440a..3c3236809 100644
--- a/go.mod
+++ b/go.mod
@@ -13,7 +13,7 @@ require (
 	github.com/onsi/ginkgo/v2 v2.23.0
 	github.com/onsi/gomega v1.36.2
 	github.com/open-policy-agent/cert-controller v0.12.0
-	github.com/project-codeflare/appwrapper v1.1.0
+	github.com/project-codeflare/appwrapper v1.1.1
 	github.com/prometheus/client_golang v1.21.1
 	github.com/prometheus/client_model v0.6.1
 	github.com/ray-project/kuberay/ray-operator v1.3.1
diff --git a/go.sum b/go.sum
index 99df8efc9..91179f694 100644
--- a/go.sum
+++ b/go.sum
@@ -169,8 +169,8 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
 github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/project-codeflare/appwrapper v1.1.0 h1:0YDti8qqsnML/YCofOSQ6az++6dhQKYqWh1UexdWrD4=
-github.com/project-codeflare/appwrapper v1.1.0/go.mod h1:Y9XqesMiT0OsHsicHYvC6/Xoj0EMYgJYUo3Vob6JvKo=
+github.com/project-codeflare/appwrapper v1.1.1 h1:ymFtH4bWpFyf4MgLvzONEgJ5A9utjAU5kSMLpSyeaBU=
+github.com/project-codeflare/appwrapper v1.1.1/go.mod h1:+Pfxe92YSxrFqO1ovRZTQ1PRrQqkdq5fLCxn1Ok6ZlQ=
 github.com/prometheus/client_golang v1.21.1 h1:DOvXXTqVzvkIewV/CDPFdejpMCGeMcbGCQ8YOmu+Ibk=
 github.com/prometheus/client_golang v1.21.1/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg=
 github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
diff --git a/hack/e2e-kueueviz-backend.sh b/hack/e2e-kueueviz-backend.sh
new file mode 100755
index 000000000..0ac0ba801
--- /dev/null
+++ b/hack/e2e-kueueviz-backend.sh
@@ -0,0 +1,74 @@
+#!/bin/bash
+
+set -e
+
+SOURCE_DIR="$(cd "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)"
+ROOT_DIR="$SOURCE_DIR/.."
+# shellcheck source=hack/e2e-common.sh
+source "${SOURCE_DIR}/e2e-common.sh"
+echo ROOT_DIR="${ROOT_DIR}" SOURCE_DIR="${SOURCE_DIR}" KIND_CLUSTER_NAME="${KIND_CLUSTER_NAME}"
+
+# if CI is true and PROW_JOB_ID is set, set NO_COLOR to 1
+if [ -n "${CI}" ] && [ -n "${PROW_JOB_ID}" ]; then
+  export NO_COLOR=1
+  echo "Running in prow: Disabling color to have readable logs: NO_COLOR=${NO_COLOR}"
+fi
+
+# Function to clean up background processes
+cleanup() {
+  echo "Cleaning up kueue-viz processes"
+  kill "${BACKEND_PID}" 
+  cluster_cleanup "${KIND_CLUSTER_NAME}"
+}
+
+# Set trap to clean up on exit
+trap cleanup EXIT
+
+echo Creating kind cluster "${KIND_CLUSTER_NAME}"
+cluster_create "${KIND_CLUSTER_NAME}"
+echo Waiting for kind cluster "${KIND_CLUSTER_NAME}" to start...
+cluster_kueue_deploy "${KIND_CLUSTER_NAME}"
+kubectl wait deploy/kueue-controller-manager -nkueue-system --for=condition=available --timeout=5m
+
+# Deploy kueue-viz resources
+kubectl create -f "${ROOT_DIR}/cmd/experimental/kueue-viz/examples/"
+
+# Start kueue-viz backend
+cd "${ROOT_DIR}/cmd/experimental/kueue-viz/backend"
+go build -o bin/kueue-viz
+./bin/kueue-viz & BACKEND_PID=$!
+cd -
+
+set -x  # Enable debug mode
+
+# Debugging: Print the container ID
+CONTAINER_ID=$(docker ps --format json | jq -r 'select(.Image | contains("kubekins-e2e")) | .ID')
+echo "Container ID: $CONTAINER_ID"
+
+# Check if the container is running
+if [ -n "$CONTAINER_ID" ]; then
+  echo "Running container found for image: $CONTAINER_ID"
+  # Extract the workspace volume
+  WORKSPACE_VOLUME=$(docker inspect "$CONTAINER_ID" | jq -r '.[] | .Mounts[] | select(.Destination=="/workspace") | .Source')
+fi
+
+# Check if the workspace volume is empty
+if [ -z "$WORKSPACE_VOLUME" ]; then
+  WORKSPACE_VOLUME=$(dirname "${SOURCE_DIR}")
+fi
+echo "Workspace Volume: $WORKSPACE_VOLUME"
+
+# if CYPRESS_IMAGE_NAME is not set, set it to cypress/base:22.14.0
+if [ -z "$CYPRESS_IMAGE_NAME" ]; then
+  CYPRESS_IMAGE_NAME="cypress/base:22.14.0"
+fi
+
+# Start kueue-viz frontend and cypress in a container
+echo "Current container information: CONTAINER_ID=${CONTAINER_ID} WORKSPACE_VOLUME=${WORKSPACE_VOLUME}"
+docker run -i --entrypoint /workspace/hack/e2e-kueueviz-frontend.sh \
+           -w /workspace --network host \
+           -v "${WORKSPACE_VOLUME}":/workspace:rw \
+           -v /var/run/docker.sock:/var/run/docker.sock "${CYPRESS_IMAGE_NAME}"
+
+set +x  # Disable debug mode
+# The trap will handle cleanup 
diff --git a/hack/e2e-kueueviz-frontend.sh b/hack/e2e-kueueviz-frontend.sh
new file mode 100755
index 000000000..ca0a9ac8f
--- /dev/null
+++ b/hack/e2e-kueueviz-frontend.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+
+set -e
+
+# if CI is true and PROW_JOB_ID is set, set NO_COLOR to 1
+if [ -n "${CI}" ] && [ -n "${PROW_JOB_ID}" ]; then
+  export NO_COLOR=1
+  echo "Running in prow: Disabling color to have readable logs: NO_COLOR=${NO_COLOR}"
+fi
+
+# Install missing dependencies
+apt-get update && apt-get install -y curl make xdg-utils
+
+# Function to clean up background processes
+cleanup() {
+  echo "Cleaning up kueue-viz processes"
+  kill "${FRONTEND_PID}"
+}
+
+# Start kueue-viz frontend
+cd cmd/experimental/kueue-viz/frontend
+npm install
+npm start & FRONTEND_PID=$!
+
+# Run Cypress tests for kueue-viz frontend
+npx cypress install
+npm run cypress:run --headless
+
+# The trap will handle cleanup 
diff --git a/hack/e2e-kueueviz-local.sh b/hack/e2e-kueueviz-local.sh
new file mode 100755
index 000000000..9168a651e
--- /dev/null
+++ b/hack/e2e-kueueviz-local.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+
+set -e
+
+SOURCE_DIR="$(cd "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)"
+ROOT_DIR="$SOURCE_DIR/.."
+# shellcheck source=hack/e2e-common.sh
+source "${SOURCE_DIR}/e2e-common.sh"
+
+# Set CYPRESS_IMAGE_NAME to the value of the env var or default to cypress/base
+CYPRESS_IMAGE_NAME="${CYPRESS_IMAGE_NAME:-cypress/base}"
+
+# Function to clean up background processes
+cleanup() {
+  echo "Cleaning up kueue-viz processes"
+  kill $BACKEND_PID $FRONTEND_PID
+  cluster_cleanup "$KIND_CLUSTER_NAME"
+}
+
+# Set trap to clean up on exit
+trap cleanup EXIT
+
+cluster_create "${KIND_CLUSTER_NAME}"
+echo Waiting for kind cluster "${KIND_CLUSTER_NAME}" to start...
+cluster_kueue_deploy "${KIND_CLUSTER_NAME}"
+kubectl wait deploy/kueue-controller-manager -nkueue-system --for=condition=available --timeout=5m
+
+# Deploy kueue-viz resources
+kubectl create -f "${ROOT_DIR}/cmd/experimental/kueue-viz/examples/"
+
+# Start kueue-viz backend
+cd "${ROOT_DIR}/cmd/experimental/kueue-viz/backend"
+go build -o bin/kueue-viz
+./bin/kueue-viz & BACKEND_PID=$!
+cd -
+
+# Start kueue-viz frontend
+cd cmd/experimental/kueue-viz/frontend
+npm start & FRONTEND_PID=$!
+
+# Run Cypress tests for kueue-viz frontend
+npm run cypress:run --headless
+
+# The trap will handle cleanup 
diff --git a/hack/push-chart.sh b/hack/push-chart.sh
index e69fb2a7a..5f499043b 100755
--- a/hack/push-chart.sh
+++ b/hack/push-chart.sh
@@ -48,9 +48,15 @@ readonly default_image_repo
 # Update the image repo, tag and policy
 ${YQ}  e  ".controllerManager.manager.image.repository = \"${image_repository}\" | .controllerManager.manager.image.tag = \"${chart_version}\" | .controllerManager.manager.image.pullPolicy = \"IfNotPresent\"" -i charts/kueue/values.yaml
 
+# Update the kueueViz images in values.yaml
+${YQ} e ".kueueViz.backend.image = \"${image_repository}/kueue-viz-backend:${chart_version}\" | .kueueViz.frontend.image = \"${image_repository}/kueue-viz-frontend:${chart_version}\"" -i charts/kueue/values.yaml
+
 ${HELM} package --version "${chart_version}" --app-version "${chart_version}" charts/kueue -d "${DEST_CHART_DIR}"
 
 # Revert the image changes
 ${YQ}  e  ".controllerManager.manager.image.repository = \"${default_image_repo}\" | .controllerManager.manager.image.tag = \"main\" | .controllerManager.manager.image.pullPolicy = \"Always\"" -i charts/kueue/values.yaml
 
+# Revert the kueueViz image changes
+${YQ} e ".kueueViz.backend.image = \"us-central1-docker.pkg.dev/k8s-staging-images/kueue/kueue-viz-backend:main\" | .kueueViz.frontend.image = \"us-central1-docker.pkg.dev/k8s-staging-images/kueue/kueue-viz-frontend:main\"" -i charts/kueue/values.yaml
+
 ${HELM} push "bin/kueue-${chart_version}.tgz" "oci://${HELM_CHART_REPO}"
diff --git a/pkg/controller/core/cohort_controller.go b/pkg/controller/core/cohort_controller.go
index 2fc7924ae..9e20aafc2 100644
--- a/pkg/controller/core/cohort_controller.go
+++ b/pkg/controller/core/cohort_controller.go
@@ -128,6 +128,7 @@ func (r *CohortReconciler) Generic(event.TypedGenericEvent[*kueue.Cohort]) bool
 }
 
 //+kubebuilder:rbac:groups=kueue.x-k8s.io,resources=cohorts,verbs=get;list;watch;create;update;patch;delete
+//+kubebuilder:rbac:groups=kueue.x-k8s.io,resources=cohorts/status,verbs=get;update;patch
 
 func (r *CohortReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
 	log := ctrl.LoggerFrom(ctx)
diff --git a/pkg/controller/jobframework/reconciler.go b/pkg/controller/jobframework/reconciler.go
index 344f6b560..ec01e22f7 100644
--- a/pkg/controller/jobframework/reconciler.go
+++ b/pkg/controller/jobframework/reconciler.go
@@ -1051,15 +1051,21 @@ func (r *JobReconciler) prepareWorkload(ctx context.Context, job GenericJob, wl
 }
 
 func (r *JobReconciler) extractPriority(ctx context.Context, podSets []kueue.PodSet, job GenericJob) (string, string, int32, error) {
-	if workloadPriorityClass := WorkloadPriorityClassName(job.Object()); len(workloadPriorityClass) > 0 {
-		return utilpriority.GetPriorityFromWorkloadPriorityClass(ctx, r.client, workloadPriorityClass)
-	}
+	var customPriorityFunc func() string
 	if jobWithPriorityClass, isImplemented := job.(JobWithPriorityClass); isImplemented {
-		return utilpriority.GetPriorityFromPriorityClass(
-			ctx, r.client, jobWithPriorityClass.PriorityClass())
+		customPriorityFunc = jobWithPriorityClass.PriorityClass
+	}
+	return ExtractPriority(ctx, r.client, job.Object(), podSets, customPriorityFunc)
+}
+
+func ExtractPriority(ctx context.Context, c client.Client, obj client.Object, podSets []kueue.PodSet, customPriorityFunc func() string) (string, string, int32, error) {
+	if workloadPriorityClass := WorkloadPriorityClassName(obj); len(workloadPriorityClass) > 0 {
+		return utilpriority.GetPriorityFromWorkloadPriorityClass(ctx, c, workloadPriorityClass)
+	}
+	if customPriorityFunc != nil {
+		return utilpriority.GetPriorityFromPriorityClass(ctx, c, customPriorityFunc())
 	}
-	return utilpriority.GetPriorityFromPriorityClass(
-		ctx, r.client, extractPriorityFromPodSets(podSets))
+	return utilpriority.GetPriorityFromPriorityClass(ctx, c, extractPriorityFromPodSets(podSets))
 }
 
 func extractPriorityFromPodSets(podSets []kueue.PodSet) string {
diff --git a/pkg/controller/jobs/leaderworkerset/leaderworkerset_pod_reconciler.go b/pkg/controller/jobs/leaderworkerset/leaderworkerset_pod_reconciler.go
index b171f96f1..907b74c68 100644
--- a/pkg/controller/jobs/leaderworkerset/leaderworkerset_pod_reconciler.go
+++ b/pkg/controller/jobs/leaderworkerset/leaderworkerset_pod_reconciler.go
@@ -127,10 +127,6 @@ func (r *PodReconciler) setDefault(ctx context.Context, pod *corev1.Pod) (bool,
 	pod.Labels[constants.QueueLabel] = queueName
 	pod.Labels[podconstants.GroupNameLabel] = wlName
 	pod.Labels[constants.PrebuiltWorkloadLabel] = wlName
-	if priorityClass := jobframework.WorkloadPriorityClassName(lws); priorityClass != "" {
-		pod.Labels[constants.WorkloadPriorityClassLabel] = priorityClass
-	}
-
 	pod.Annotations[podconstants.GroupTotalCountAnnotation] = fmt.Sprint(ptr.Deref(lws.Spec.LeaderWorkerTemplate.Size, 1))
 	pod.Annotations[podconstants.RoleHashAnnotation] = string(kueue.DefaultPodSetName)
 
diff --git a/pkg/controller/jobs/leaderworkerset/leaderworkerset_reconciler.go b/pkg/controller/jobs/leaderworkerset/leaderworkerset_reconciler.go
index 9bf1e0d47..e49168e5c 100644
--- a/pkg/controller/jobs/leaderworkerset/leaderworkerset_reconciler.go
+++ b/pkg/controller/jobs/leaderworkerset/leaderworkerset_reconciler.go
@@ -112,7 +112,17 @@ func (r *Reconciler) createPrebuiltWorkloadIfNotExist(ctx context.Context, lws *
 
 func (r *Reconciler) createPrebuiltWorkload(ctx context.Context, lws *leaderworkersetv1.LeaderWorkerSet, index int32) error {
 	createdWorkload := r.constructWorkload(lws, index)
-	err := r.client.Create(ctx, createdWorkload)
+
+	priorityClassName, source, p, err := jobframework.ExtractPriority(ctx, r.client, lws, createdWorkload.Spec.PodSets, nil)
+	if err != nil {
+		return err
+	}
+
+	createdWorkload.Spec.PriorityClassName = priorityClassName
+	createdWorkload.Spec.Priority = &p
+	createdWorkload.Spec.PriorityClassSource = source
+
+	err = r.client.Create(ctx, createdWorkload)
 	if err != nil {
 		return err
 	}
diff --git a/pkg/controller/jobs/leaderworkerset/leaderworkerset_webhook.go b/pkg/controller/jobs/leaderworkerset/leaderworkerset_webhook.go
index af254b5f3..0c3a2a0ea 100644
--- a/pkg/controller/jobs/leaderworkerset/leaderworkerset_webhook.go
+++ b/pkg/controller/jobs/leaderworkerset/leaderworkerset_webhook.go
@@ -72,17 +72,24 @@ func (wh *Webhook) Default(ctx context.Context, obj runtime.Object) error {
 	}
 	if suspend {
 		if lws.Spec.LeaderWorkerTemplate.LeaderTemplate != nil {
-			wh.podTemplateSpecDefault(lws.Spec.LeaderWorkerTemplate.LeaderTemplate)
+			wh.podTemplateSpecDefault(lws, lws.Spec.LeaderWorkerTemplate.LeaderTemplate)
 		}
-		wh.podTemplateSpecDefault(&lws.Spec.LeaderWorkerTemplate.WorkerTemplate)
+		wh.podTemplateSpecDefault(lws, &lws.Spec.LeaderWorkerTemplate.WorkerTemplate)
 	}
 
 	return nil
 }
 
-func (wh *Webhook) podTemplateSpecDefault(podTemplateSpec *corev1.PodTemplateSpec) {
+func (wh *Webhook) podTemplateSpecDefault(lws *LeaderWorkerSet, podTemplateSpec *corev1.PodTemplateSpec) {
+	if priorityClass := jobframework.WorkloadPriorityClassName(lws.Object()); priorityClass != "" {
+		if podTemplateSpec.Labels == nil {
+			podTemplateSpec.Labels = make(map[string]string, 1)
+		}
+		podTemplateSpec.Labels[constants.WorkloadPriorityClassLabel] = priorityClass
+	}
+
 	if podTemplateSpec.Annotations == nil {
-		podTemplateSpec.Annotations = make(map[string]string, 1)
+		podTemplateSpec.Annotations = make(map[string]string, 2)
 	}
 	podTemplateSpec.Annotations[podconstants.SuspendedByParentAnnotation] = FrameworkName
 	podTemplateSpec.Annotations[podconstants.GroupServingAnnotationKey] = podconstants.GroupServingAnnotationValue
diff --git a/site/content/en/docs/concepts/multikueue.md b/site/content/en/docs/concepts/multikueue.md
index d70c9bf4e..b41e505f3 100644
--- a/site/content/en/docs/concepts/multikueue.md
+++ b/site/content/en/docs/concepts/multikueue.md
@@ -72,7 +72,7 @@ We recommend using JobSet v0.5.1 or newer.
 
 ### Kubeflow
 
-The supported version of the Kubeflow Training Operator is v1.7.0, or a newer version.
+The supported version of the Kubeflow Trainer is v1.7.0, or a newer version.
 The Management cluster should only install the CRDs and not the package itself. 
 On the other hand, the Worker cluster should install the full kubeflow operator.
 
diff --git a/site/content/en/docs/contribution_guidelines/testing.md b/site/content/en/docs/contribution_guidelines/testing.md
index b231ddb04..45e9799df 100644
--- a/site/content/en/docs/contribution_guidelines/testing.md
+++ b/site/content/en/docs/contribution_guidelines/testing.md
@@ -53,21 +53,14 @@ make test-integration
 
 For running a subset of tests, see [Running subset of tests](#running-subset-of-integration-or-e2e-tests).
 
-### Increase logging verbosity
-You can change log level in the framework (for example, change -3 to -5 to increase verbosity):
-https://github.com/kubernetes-sigs/kueue/blob/f8015cb273f9115c34f9be32b35f7e1308c16459/test/integration/framework/framework.go#L72:
-```go
-var setupLogger = sync.OnceFunc(func() {
-	ctrl.SetLogger(util.NewTestingLogger(ginkgo.GinkgoWriter, -3))
-})
-```
-
 ## Running e2e tests using custom build
 ```shell
 make kind-image-build
 make test-e2e
 make test-tas-e2e
 make test-e2e-customconfigs
+make test-e2e-certmanager
+make test-e2e-kueueviz
 make test-multikueue-e2e
 ```
 
@@ -78,6 +71,10 @@ E2E_KIND_VERSION=kindest/node:v1.32.0 make test-e2e
 
 For running a subset of tests, see [Running subset of tests](#running-subset-of-integration-or-e2e-tests).
 
+## Increase logging verbosity
+You can change log level (for example, set -5 to increase verbosity) using `TEST_LOG_LEVEL` variables.
+By default, `TEST_LOG_LEVEL=-3`.
+
 ## Debug tests in VSCode
 It is possible to debug unit and integration tests in VSCode.
 You need to have the [Go extension](https://marketplace.visualstudio.com/items?itemName=golang.Go) installed.
diff --git a/site/content/en/docs/reference/kueue-alpha.v1alpha1.md b/site/content/en/docs/reference/kueue-alpha.v1alpha1.md
index 36ba04206..620af7793 100644
--- a/site/content/en/docs/reference/kueue-alpha.v1alpha1.md
+++ b/site/content/en/docs/reference/kueue-alpha.v1alpha1.md
@@ -145,6 +145,8 @@ if FairSharing is enabled in the Kueue configuration.</p>
 - [Cohort](#kueue-x-k8s-io-v1alpha1-Cohort)
 
 
+<p>CohortStatus defines the observed state of Cohort.</p>
+
 
 <table class="table">
 <thead><tr><th width="30%">Field</th><th>Description</th></tr></thead>
@@ -155,7 +157,10 @@ if FairSharing is enabled in the Kueue configuration.</p>
 <a href="#kueue-x-k8s-io-v1beta1-FairSharingStatus"><code>FairSharingStatus</code></a>
 </td>
 <td>
-   <span class="text-muted">No description provided.</span></td>
+   <p>fairSharing contains the current state for this Cohort
+when participating in Fair Sharing.
+The is recorded only when Fair Sharing is enabled in the Kueue configuration.</p>
+</td>
 </tr>
 </tbody>
 </table>
diff --git a/site/content/en/docs/reference/kueue.v1beta1.md b/site/content/en/docs/reference/kueue.v1beta1.md
index 08f65f7bf..ca4f30cab 100644
--- a/site/content/en/docs/reference/kueue.v1beta1.md
+++ b/site/content/en/docs/reference/kueue.v1beta1.md
@@ -999,7 +999,10 @@ instead.</p>
 <a href="#kueue-x-k8s-io-v1beta1-FairSharingStatus"><code>FairSharingStatus</code></a>
 </td>
 <td>
-   <span class="text-muted">No description provided.</span></td>
+   <p>fairSharing contains the current state for this ClusterQueue
+when participating in Fair Sharing.
+This is recorded only when Fair Sharing is enabled in the Kueue configuration.</p>
+</td>
 </tr>
 </tbody>
 </table>
@@ -1067,7 +1070,7 @@ disadvantage against other ClusterQueues and Cohorts.</p>
 - [ClusterQueueStatus](#kueue-x-k8s-io-v1beta1-ClusterQueueStatus)
 
 
-<p>fairSharing contains the information about the current status of Fair Sharing.</p>
+<p>FairSharingStatus contains the information about the current status of Fair Sharing.</p>
 
 
 <table class="table">
@@ -1079,7 +1082,7 @@ disadvantage against other ClusterQueues and Cohorts.</p>
 <code>int64</code>
 </td>
 <td>
-   <p>WeightedShare represent the maximum of the ratios of usage
+   <p>WeightedShare represents the maximum of the ratios of usage
 above nominal quota to the lendable resources in the
 Cohort, among all the resources provided by the Node, and
 divided by the weight.  If zero, it means that the usage of
diff --git a/site/content/en/docs/tasks/manage/setup_multikueue.md b/site/content/en/docs/tasks/manage/setup_multikueue.md
index 29e6aabaa..07d1f4ca8 100644
--- a/site/content/en/docs/tasks/manage/setup_multikueue.md
+++ b/site/content/en/docs/tasks/manage/setup_multikueue.md
@@ -51,7 +51,7 @@ To create a Kubeconfig that can be used in the manager cluster to delegate Jobs
 
 ### Kubeflow Installation
 
-Install Kubeflow Training-operator in the Worker cluster (see [Kubeflow Training-operator Installation](https://www.kubeflow.org/docs/components/training/installation/)
+Install Kubeflow Trainer in the Worker cluster (see [Kubeflow Trainer Installation](https://www.kubeflow.org/docs/components/training/installation/)
 for more details). Please use version v1.7.0 or a newer version for MultiKueue.
 
 ## In the Manager Cluster
diff --git a/site/content/en/docs/tasks/run/kubeflow/_index.md b/site/content/en/docs/tasks/run/kubeflow/_index.md
index 3fdb6a977..cbb1e71c7 100755
--- a/site/content/en/docs/tasks/run/kubeflow/_index.md
+++ b/site/content/en/docs/tasks/run/kubeflow/_index.md
@@ -14,7 +14,12 @@ The tasks below show you how to run Kueue managed Kubeflow Jobs.
 ### [MPI Operator](https://github.com/kubeflow/mpi-operator) Integration
 - [Run a Kueue managed Kubeflow MPIJob](/docs/tasks/run_kubeflow_jobs/run_mpijobs).
 
-### [Training Operator](https://github.com/kubeflow/training-operator) Integration
+### [Trainer](https://github.com/kubeflow/trainer) Integration
+
+{{% alert title="Note" color="primary" %}}
+Kueue supports only traditional Jobs served until Trainer v1.9.x and does not support new TrainJob. 
+{{% /alert %}}
+
 - [Run a Kueue managed Kubeflow PyTorchJob](/docs/tasks/run_kubeflow_jobs/run_pytorchjobs).
 - [Run a Kueue managed Kubeflow TFJob](/docs/tasks/run_kubeflow_jobs/run_tfjobs).
 - [Run a Kueue managed Kubeflow XGBoostJob](/docs/tasks/run_kubeflow_jobs/run_xgboostjobs).
diff --git a/site/content/en/docs/tasks/run/kubeflow/mpijobs.md b/site/content/en/docs/tasks/run/kubeflow/mpijobs.md
index 6e8173848..219dafa89 100644
--- a/site/content/en/docs/tasks/run/kubeflow/mpijobs.md
+++ b/site/content/en/docs/tasks/run/kubeflow/mpijobs.md
@@ -24,8 +24,8 @@ You can do it by running: `kubectl delete pods -lcontrol-plane=controller-manage
 {{% /alert %}}
 
 {{% alert title="Note" color="primary" %}}
-While using both MPI Operator and Training Operator, it is required to disable Training Operator's MPIJob option.
-Training Operator deployment needs to be  modified to enable all kubeflow jobs except MPIJob, as mentioned [here](https://github.com/kubeflow/training-operator/issues/1777).
+While using both MPI Operator and Trainer, it is required to disable Trainer's MPIJob option.
+Trainer deployment needs to be  modified to enable all kubeflow jobs except MPIJob, as mentioned [here](https://github.com/kubeflow/trainer/issues/1777).
 {{% /alert %}}
 
 ## MPI Operator definition
diff --git a/site/content/en/docs/tasks/run/kubeflow/paddlejobs.md b/site/content/en/docs/tasks/run/kubeflow/paddlejobs.md
index ca79c080f..bcc04f21f 100644
--- a/site/content/en/docs/tasks/run/kubeflow/paddlejobs.md
+++ b/site/content/en/docs/tasks/run/kubeflow/paddlejobs.md
@@ -6,7 +6,7 @@ description: >
   Run a Kueue scheduled PaddleJob
 ---
 
-This page shows how to leverage Kueue's scheduling and resource management capabilities when running [Training Operator](https://www.kubeflow.org/docs/components/training/paddlepaddle/) PaddleJobs.
+This page shows how to leverage Kueue's scheduling and resource management capabilities when running [Trainer](https://www.kubeflow.org/docs/components/training/paddlepaddle/) PaddleJobs.
 
 This guide is for [batch users](/docs/tasks#batch-user) that have a basic understanding of Kueue. For more information, see [Kueue's overview](/docs/overview).
 
@@ -14,14 +14,14 @@ This guide is for [batch users](/docs/tasks#batch-user) that have a basic unders
 
 Check [administer cluster quotas](/docs/tasks/manage/administer_cluster_quotas) for details on the initial cluster setup.
 
-Check [the Training Operator installation guide](https://github.com/kubeflow/training-operator#installation).
+Check [the Trainer installation guide](https://www.kubeflow.org/docs/components/training/installation/).
 
-Note that the minimum requirement training-operator version is v1.7.0.
+Note that the minimum requirement trainer version is v1.7.0.
 
 You can [modify kueue configurations from installed releases](/docs/installation#install-a-custom-configured-released-version) to include PaddleJobs as an allowed workload.
 
 {{% alert title="Note" color="primary" %}}
-In order to use Training Operator, prior to v0.8.1, you need to restart Kueue after the installation.
+In order to use Trainer, prior to v0.8.1, you need to restart Kueue after the installation.
 You can do it by running: `kubectl delete pods -lcontrol-plane=controller-manager -nkueue-system`.
 {{% /alert %}}
 
@@ -49,6 +49,6 @@ By default, Kueue will set `suspend` to true via webhook and unsuspend it when t
 
 ## Sample PaddleJob
 
-This example is based on https://github.com/kubeflow/training-operator/blob/288d680a699237fb61a74ada005e202721815ff2/examples/paddlepaddle/simple-cpu.yaml.
+This example is based on https://github.com/kubeflow/trainer/blob/288d680a699237fb61a74ada005e202721815ff2/examples/paddlepaddle/simple-cpu.yaml.
 
 {{< include "examples/jobs/sample-paddlejob.yaml" "yaml" >}}
diff --git a/site/content/en/docs/tasks/run/kubeflow/pytorchjobs.md b/site/content/en/docs/tasks/run/kubeflow/pytorchjobs.md
index 3cb868632..8fd436dd2 100644
--- a/site/content/en/docs/tasks/run/kubeflow/pytorchjobs.md
+++ b/site/content/en/docs/tasks/run/kubeflow/pytorchjobs.md
@@ -6,7 +6,7 @@ description: >
   Run a Kueue scheduled PyTorchJob
 ---
 
-This page shows how to leverage Kueue's scheduling and resource management capabilities when running [Training Operator](https://www.kubeflow.org/docs/components/training/pytorch/) PyTorchJobs.
+This page shows how to leverage Kueue's scheduling and resource management capabilities when running [Trainer](https://www.kubeflow.org/docs/components/training/pytorch/) PyTorchJobs.
 
 This guide is for [batch users](/docs/tasks#batch-user) that have a basic understanding of Kueue. For more information, see [Kueue's overview](/docs/overview).
 
@@ -14,14 +14,14 @@ This guide is for [batch users](/docs/tasks#batch-user) that have a basic unders
 
 Check [administer cluster quotas](/docs/tasks/manage/administer_cluster_quotas) for details on the initial cluster setup.
 
-Check [the Training Operator installation guide](https://github.com/kubeflow/training-operator#installation).
+Check [the Trainer installation guide](https://www.kubeflow.org/docs/components/training/installation/).
 
-Note that the minimum requirement training-operator version is v1.7.0.
+Note that the minimum requirement trainer version is v1.7.0.
 
 You can [modify kueue configurations from installed releases](/docs/installation#install-a-custom-configured-released-version) to include PyTorchJobs as an allowed workload.
 
 {{% alert title="Note" color="primary" %}}
-In order to use Training Operator, prior to v0.8.1, you need to restart Kueue after the installation.
+In order to use Trainer, prior to v0.8.1, you need to restart Kueue after the installation.
 You can do it by running: `kubectl delete pods -lcontrol-plane=controller-manager -nkueue-system`.
 {{% /alert %}}
 
@@ -49,6 +49,6 @@ By default, Kueue will set `suspend` to true via webhook and unsuspend it when t
 
 ## Sample PyTorchJob
 
-This example is based on https://github.com/kubeflow/training-operator/blob/855e0960668b34992ba4e1fd5914a08a3362cfb1/examples/pytorch/simple.yaml.
+This example is based on https://github.com/kubeflow/trainer/blob/855e0960668b34992ba4e1fd5914a08a3362cfb1/examples/pytorch/simple.yaml.
 
 {{< include "examples/jobs/sample-pytorchjob.yaml" "yaml" >}}
diff --git a/site/content/en/docs/tasks/run/kubeflow/tfjobs.md b/site/content/en/docs/tasks/run/kubeflow/tfjobs.md
index 7d6ea7965..b4d5bbf01 100644
--- a/site/content/en/docs/tasks/run/kubeflow/tfjobs.md
+++ b/site/content/en/docs/tasks/run/kubeflow/tfjobs.md
@@ -6,7 +6,7 @@ description: >
   Run a Kueue scheduled TFJob
 ---
 
-This page shows how to leverage Kueue's scheduling and resource management capabilities when running [Training Operator](https://www.kubeflow.org/docs/components/training/tftraining/) TFJobs.
+This page shows how to leverage Kueue's scheduling and resource management capabilities when running [Trainer](https://www.kubeflow.org/docs/components/training/tftraining/) TFJobs.
 
 This guide is for [batch users](/docs/tasks#batch-user) that have a basic understanding of Kueue. For more information, see [Kueue's overview](/docs/overview).
 
@@ -14,14 +14,14 @@ This guide is for [batch users](/docs/tasks#batch-user) that have a basic unders
 
 Check [administer cluster quotas](/docs/tasks/manage/administer_cluster_quotas) for details on the initial cluster setup.
 
-Check [the Training Operator installation guide](https://github.com/kubeflow/training-operator#installation).
+Check [the Trainer installation guide](https://www.kubeflow.org/docs/components/training/installation/).
 
-Note that the minimum requirement training-operator version is v1.7.0.
+Note that the minimum requirement trainer version is v1.7.0.
 
 You can [modify kueue configurations from installed releases](/docs/installation#install-a-custom-configured-released-version) to include TFJobs as an allowed workload.
 
 {{% alert title="Note" color="primary" %}}
-In order to use Training Operator, prior to v0.8.1, you need to restart Kueue after the installation.
+In order to use Trainer, prior to v0.8.1, you need to restart Kueue after the installation.
 You can do it by running: `kubectl delete pods -lcontrol-plane=controller-manager -nkueue-system`.
 {{% /alert %}}
 
@@ -49,6 +49,6 @@ By default, Kueue will set `suspend` to true via webhook and unsuspend it when t
 
 ## Sample TFJob
 
-This example is based on https://github.com/kubeflow/training-operator/blob/48dbbf0a8e90e52c55ec05d0f689fcbf83c6b441/examples/tensorflow/dist-mnist/tf_job_mnist.yaml.
+This example is based on https://github.com/kubeflow/trainer/blob/48dbbf0a8e90e52c55ec05d0f689fcbf83c6b441/examples/tensorflow/dist-mnist/tf_job_mnist.yaml.
 
 {{< include "examples/jobs/sample-tfjob.yaml" "yaml" >}}
diff --git a/site/content/en/docs/tasks/run/kubeflow/xgboostjobs.md b/site/content/en/docs/tasks/run/kubeflow/xgboostjobs.md
index 5566f4ce3..39de7cf7a 100644
--- a/site/content/en/docs/tasks/run/kubeflow/xgboostjobs.md
+++ b/site/content/en/docs/tasks/run/kubeflow/xgboostjobs.md
@@ -6,7 +6,8 @@ description: >
   Run a Kueue scheduled XGBoostJob
 ---
 
-This page shows how to leverage Kueue's scheduling and resource management capabilities when running [Training Operator](https://www.kubeflow.org/docs/components/training/xgboost/) XGBoostJobs.
+This page shows how to leverage Kueue's scheduling and resource management capabilities when running 
+[Trainer](https://www.kubeflow.org/docs/components/training/xgboost/) XGBoostJobs.
 
 This guide is for [batch users](/docs/tasks#batch-user) that have a basic understanding of Kueue. For more information, see [Kueue's overview](/docs/overview).
 
@@ -14,14 +15,14 @@ This guide is for [batch users](/docs/tasks#batch-user) that have a basic unders
 
 Check [administer cluster quotas](/docs/tasks/manage/administer_cluster_quotas) for details on the initial cluster setup.
 
-Check [the Training Operator installation guide](https://github.com/kubeflow/training-operator#installation).
+Check [the Trainer installation guide](https://www.kubeflow.org/docs/components/training/installation/).
 
-Note that the minimum requirement training-operator version is v1.7.0.
+Note that the minimum requirement trainer version is v1.7.0.
 
 You can [modify kueue configurations from installed releases](/docs/installation#install-a-custom-configured-released-version) to include XGBoostJobs as an allowed workload.
 
 {{% alert title="Note" color="primary" %}}
-In order to use Training Operator, prior to v0.8.1, you need to restart Kueue after the installation.
+In order to use Trainer, prior to v0.8.1, you need to restart Kueue after the installation.
 You can do it by running: `kubectl delete pods -lcontrol-plane=controller-manager -nkueue-system`.
 {{% /alert %}}
 
@@ -49,6 +50,6 @@ By default, Kueue will set `suspend` to true via webhook and unsuspend it when t
 
 ## Sample XGBoostJob
 
-This example is based on https://github.com/kubeflow/training-operator/blob/afba76bc5a168cbcbc8685c7661f36e9b787afd1/examples/xgboost/xgboostjob.yaml.
+This example is based on https://github.com/kubeflow/trainer/blob/afba76bc5a168cbcbc8685c7661f36e9b787afd1/examples/xgboost/xgboostjob.yaml.
 
 {{< include "examples/jobs/sample-xgboostjob.yaml" "yaml" >}}
diff --git a/site/content/en/docs/tasks/run/multikueue/kubeflow.md b/site/content/en/docs/tasks/run/multikueue/kubeflow.md
index 959d32150..0a75e3f4d 100644
--- a/site/content/en/docs/tasks/run/multikueue/kubeflow.md
+++ b/site/content/en/docs/tasks/run/multikueue/kubeflow.md
@@ -11,16 +11,16 @@ description: >
 
 Check the [MultiKueue installation guide](/docs/tasks/manage/setup_multikueue) on how to properly setup MultiKueue clusters.
 
-For the ease of setup and use we recommend using at least Kueue v0.11.0 and for Kubeflow Training Operator at least v1.9.0.
+For the ease of setup and use we recommend using at least Kueue v0.11.0 and for Kubeflow Trainer at least v1.9.0.
 
-See [Training Operator Installation](https://www.kubeflow.org/docs/components/training/installation/#installing-the-training-operator) for installation and configuration details of Training Operator.
+See [Trainer Installation](https://www.kubeflow.org/docs/components/training/installation/#installing-the-training-operator) for installation and configuration details of Trainer.
 
 {{% alert title="Note" color="info" %}}
-Before the [ManagedBy feature](https://github.com/kubeflow/training-operator/issues/2193) was supported in Kueue (below v0.11.0), the installation of Kubeflow Training Operator in the <b>Manager Cluster</b> must be limited to CRDs only.
+Before the [ManagedBy feature](https://github.com/kubeflow/trainer/issues/2193) was supported in Kueue (below v0.11.0), the installation of Kubeflow Trainer in the <b>Manager Cluster</b> must be limited to CRDs only.
 
 To install the CRDs run:
 ```bash
-kubectl apply -k "github.com/kubeflow/training-operator.git/manifests/base/crds?ref=v1.9.0"
+kubectl apply -k "github.com/kubeflow/trainer.git/manifests/base/crds?ref=v1.9.0"
 ```
 {{% /alert %}}
 
@@ -31,14 +31,14 @@ Once the setup is complete you can test it by running one of the Kubeflow Jobs e
 {{% alert title="Note" color="primary" %}}
 Note: Kueue defaults the `spec.runPolicy.managedBy` field to `kueue.x-k8s.io/multikueue` on the management cluster for all Kubeflow Jobs. 
 
-This allows the Training Operator to ignore the Jobs managed by MultiKueue on the management cluster, and in particular skip Pod creation. 
+This allows the Trainer to ignore the Jobs managed by MultiKueue on the management cluster, and in particular skip Pod creation. 
 
 The pods are created and the actual computation will happen on the mirror copy of the Job on the selected worker cluster. 
 The mirror copy of the Job does not have the field set.
 {{% /alert %}}
 
 ## Working alongside MPI Operator
-In order for MPI-operator and Training-operator to work on the same cluster it is required that:
-1. `kubeflow.org_mpijobs.yaml` entry is removed from `base/crds/kustomization.yaml` - https://github.com/kubeflow/training-operator/issues/1930
-2. Training Operator deployment is modified to enable all kubeflow jobs except for MPI -  https://github.com/kubeflow/training-operator/issues/1777
+In order for MPI-operator and Trainer to work on the same cluster it is required that:
+1. `kubeflow.org_mpijobs.yaml` entry is removed from `base/crds/kustomization.yaml` - https://github.com/kubeflow/trainer/issues/1930
+2. Trainer deployment is modified to enable all kubeflow jobs except for MPI -  https://github.com/kubeflow/trainer/issues/1777
   
\ No newline at end of file
diff --git a/site/content/en/docs/tasks/run/multikueue/kuberay.md b/site/content/en/docs/tasks/run/multikueue/kuberay.md
index 1494a6327..622373252 100644
--- a/site/content/en/docs/tasks/run/multikueue/kuberay.md
+++ b/site/content/en/docs/tasks/run/multikueue/kuberay.md
@@ -1,22 +1,22 @@
 ---
-title: "Run Kuberay Jobs in Multi-Cluster"
-linkTitle: "Kuberay"
+title: "Run KubeRay Jobs in Multi-Cluster"
+linkTitle: "KubeRay"
 weight: 4
 date: 2025-03-19
 description: >
-  Run a MultiKueue scheduled Kuberay Jobs.
+  Run a MultiKueue scheduled KubeRay Jobs.
 ---
 
 ## Before you begin
 
 Check the [MultiKueue installation guide](/docs/tasks/manage/setup_multikueue) on how to properly setup MultiKueue clusters.
 
-For the ease of setup and use we recommend using at least Kueue v0.11.0 and for Kuberay Operator at least v1.3.1.
+For the ease of setup and use we recommend using at least Kueue v0.11.0 and for KubeRay Operator at least v1.3.1.
 
-See [Kuberay Operator Installation](https://docs.ray.io/en/latest/cluster/kubernetes/getting-started/raycluster-quick-start.html#step-2-deploy-a-kuberay-operator) for installation and configuration details of Kuberay Operator.
+See [KubeRay Operator Installation](https://docs.ray.io/en/latest/cluster/kubernetes/getting-started/raycluster-quick-start.html#step-2-deploy-a-kuberay-operator) for installation and configuration details of KubeRay Operator.
 
 {{% alert title="Note" color="info" %}}
-Before the [ManagedBy feature](https://github.com/ray-project/kuberay/issues/2544) was supported in Kueue (below v0.11.0), the installation of Kuberay Operator in the <b>Manager Cluster</b> must be limited to CRDs only.
+Before the [ManagedBy feature](https://github.com/ray-project/kuberay/issues/2544) was supported in Kueue (below v0.11.0), the installation of KubeRay Operator in the <b>Manager Cluster</b> must be limited to CRDs only.
 
 To install the CRDs run:
 ```bash
@@ -29,9 +29,9 @@ kubectl create -k "github.com/ray-project/kuberay/ray-operator/config/crd?ref=v1
 Once the setup is complete you can test it by running a RayJob [`ray-job-sample.yaml`](/docs/tasks/run/rayjobs/#example-rayjob).
 
 {{% alert title="Note" color="primary" %}}
-Note: Kueue defaults the `spec.runPolicy.managedBy` field to `kueue.x-k8s.io/multikueue` on the management cluster for Kuberay Jobs (RayJob, RayCluster, RayService). 
+Note: Kueue defaults the `spec.managedBy` field to `kueue.x-k8s.io/multikueue` on the management cluster for KubeRay Jobs (RayJob, RayCluster, RayService). 
 
-This allows the Kuberay Operator to ignore the Jobs managed by MultiKueue on the management cluster, and in particular skip Pod creation. 
+This allows the KubeRay Operator to ignore the Jobs managed by MultiKueue on the management cluster, and in particular skip Pod creation. 
 
 The pods are created and the actual computation will happen on the mirror copy of the Job on the selected worker cluster. 
 The mirror copy of the Job does not have the field set.
diff --git a/site/content/en/docs/tasks/run/multikueue/mpijob.md b/site/content/en/docs/tasks/run/multikueue/mpijob.md
index 9b019b7ac..0efabdc74 100644
--- a/site/content/en/docs/tasks/run/multikueue/mpijob.md
+++ b/site/content/en/docs/tasks/run/multikueue/mpijob.md
@@ -16,7 +16,7 @@ For the proper setup and use it is required using at least Kueue v0.9.0 and for
 ### Installation on the Clusters
 
 {{% alert title="Note" color="primary" %}}
-Note: While both MPI Operator and Training Operator must be running on the same cluster, there are special steps that has to be applied to Training Operator deployment.
+Note: While both MPI Operator and Trainer must be running on the same cluster, there are special steps that has to be applied to Trainer deployment.
 See [Working alongside MPI Operator](/docs/tasks/run/multikueue/kubeflow#working-alongside-mpi-operator) for more details.
 {{% /alert %}}
 
diff --git a/site/hugo.toml b/site/hugo.toml
index 2fd72af20..e2beb19d2 100644
--- a/site/hugo.toml
+++ b/site/hugo.toml
@@ -90,10 +90,10 @@ ignoreFiles = []
   # The major.minor version tag for the version of the docs represented in this
   # branch of the repository. Used in the "version-banner" partial to display a
   # version number for this doc set.
-  version = "v0.10.3"
+  version = "v0.11.1"
 
   # Version of Kueue without the leading "v", as used for Helm charts.
-  chart_version = "0.10.3"
+  chart_version = "0.11.1"
 
   # Flag used in the "version-banner" partial to decide whether to display a
   # banner on every page indicating that this is an archived version of the docs.
diff --git a/vendor/github.com/project-codeflare/appwrapper/pkg/utils/utils.go b/vendor/github.com/project-codeflare/appwrapper/pkg/utils/utils.go
index ec0a40f3a..e3bcad715 100644
--- a/vendor/github.com/project-codeflare/appwrapper/pkg/utils/utils.go
+++ b/vendor/github.com/project-codeflare/appwrapper/pkg/utils/utils.go
@@ -22,13 +22,7 @@ import (
 	"strconv"
 	"strings"
 
-	//  Import the crypto sha256 algorithm for the docker image parser to work
-	_ "crypto/sha256"
-	//  Import the crypto/sha512 algorithm for the docker image parser to work with 384 and 512 sha hashes
-	_ "crypto/sha512"
-
 	dockerref "github.com/distribution/reference"
-
 	kftraining "github.com/kubeflow/training-operator/pkg/apis/kubeflow.org/v1"
 	batchv1 "k8s.io/api/batch/v1"
 	v1 "k8s.io/api/core/v1"
@@ -39,6 +33,11 @@ import (
 	jobsetapi "sigs.k8s.io/jobset/api/jobset/v1alpha2"
 
 	awv1beta2 "github.com/project-codeflare/appwrapper/api/v1beta2"
+
+	//  Import the crypto sha256 algorithm for the docker image parser to work
+	_ "crypto/sha256"
+	//  Import the crypto/sha512 algorithm for the docker image parser to work with 384 and 512 sha hashes
+	_ "crypto/sha512"
 )
 
 const templateString = "template"
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 7672ba6b2..e30675ddd 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -292,7 +292,7 @@ github.com/peterbourgon/diskv
 # github.com/pkg/errors v0.9.1
 ## explicit
 github.com/pkg/errors
-# github.com/project-codeflare/appwrapper v1.1.0
+# github.com/project-codeflare/appwrapper v1.1.1
 ## explicit; go 1.23.0
 github.com/project-codeflare/appwrapper/api/v1beta2
 github.com/project-codeflare/appwrapper/pkg/utils



Test patch:
diff --git a/cmd/importer/pod/check_test.go b/cmd/importer/pod/check_test.go
index 3a9ec570a..bf8ca8452 100644
--- a/cmd/importer/pod/check_test.go
+++ b/cmd/importer/pod/check_test.go
@@ -17,7 +17,6 @@ limitations under the License.
 package pod
 
 import (
-	"context"
 	"testing"
 
 	"github.com/google/go-cmp/cmp"
@@ -156,7 +155,7 @@ func TestCheckNamespace(t *testing.T) {
 			builder = builder.WithLists(&podsList, &cqList, &lqList, &rfList)
 
 			client := builder.Build()
-			ctx := context.Background()
+			ctx := t.Context()
 
 			mpc, _ := util.LoadImportCache(ctx, client, []string{testingNamespace}, tc.mapping, nil)
 			gotErr := Check(ctx, client, mpc, 8)
diff --git a/cmd/importer/pod/import_test.go b/cmd/importer/pod/import_test.go
index c72181797..a57b63b13 100644
--- a/cmd/importer/pod/import_test.go
+++ b/cmd/importer/pod/import_test.go
@@ -17,7 +17,6 @@ limitations under the License.
 package pod
 
 import (
-	"context"
 	"testing"
 
 	"github.com/google/go-cmp/cmp"
@@ -178,7 +177,7 @@ func TestImportNamespace(t *testing.T) {
 				WithLists(&podsList, &cqList, &lqList)
 
 			client := builder.Build()
-			ctx := context.Background()
+			ctx := t.Context()
 
 			mpc, _ := util.LoadImportCache(ctx, client, []string{testingNamespace}, tc.mapping, tc.addLabels)
 			gotErr := Import(ctx, client, mpc, 8)
diff --git a/cmd/kueuectl/app/create/create_resourceflavor_test.go b/cmd/kueuectl/app/create/create_resourceflavor_test.go
index 53c29711b..88743a47b 100644
--- a/cmd/kueuectl/app/create/create_resourceflavor_test.go
+++ b/cmd/kueuectl/app/create/create_resourceflavor_test.go
@@ -17,7 +17,6 @@ limitations under the License.
 package create
 
 import (
-	"context"
 	"fmt"
 	"testing"
 
@@ -358,7 +357,7 @@ func TestResourceFlavorCmd(t *testing.T) {
 				t.Errorf("Unexpected output (-want/+got)\n%s", diff)
 			}
 
-			gotRf, err := clientset.KueueV1beta1().ResourceFlavors().Get(context.Background(), tc.rfName, metav1.GetOptions{})
+			gotRf, err := clientset.KueueV1beta1().ResourceFlavors().Get(t.Context(), tc.rfName, metav1.GetOptions{})
 			if client.IgnoreNotFound(err) != nil {
 				t.Error(err)
 				return
diff --git a/cmd/kueuectl/app/delete/delete_workload_test.go b/cmd/kueuectl/app/delete/delete_workload_test.go
index ab55fab09..07dc7f9df 100644
--- a/cmd/kueuectl/app/delete/delete_workload_test.go
+++ b/cmd/kueuectl/app/delete/delete_workload_test.go
@@ -17,7 +17,6 @@ limitations under the License.
 package delete
 
 import (
-	"context"
 	"slices"
 	"testing"
 
@@ -353,7 +352,7 @@ Do you want to proceed (y/n)? jobs.batch/j1 deleted
 				t.Errorf("Unexpected error output (-want/+got)\n%s", diff)
 			}
 
-			gotWorkloadList, err := clientset.KueueV1beta1().Workloads(tc.ns).List(context.Background(), metav1.ListOptions{})
+			gotWorkloadList, err := clientset.KueueV1beta1().Workloads(tc.ns).List(t.Context(), metav1.ListOptions{})
 			if err != nil {
 				t.Fatal(err)
 			}
@@ -366,7 +365,7 @@ Do you want to proceed (y/n)? jobs.batch/j1 deleted
 			}
 
 			unstructured, err := dynamicClient.Resource(mapping.Resource).Namespace(metav1.NamespaceDefault).
-				List(context.Background(), metav1.ListOptions{})
+				List(t.Context(), metav1.ListOptions{})
 			if err != nil {
 				t.Error(err)
 				return
diff --git a/pkg/cache/cache_test.go b/pkg/cache/cache_test.go
index 33528bc28..7bda6c681 100644
--- a/pkg/cache/cache_test.go
+++ b/pkg/cache/cache_test.go
@@ -88,7 +88,7 @@ func TestCacheClusterQueueOperations(t *testing.T) {
 				NodeLabel("cpuType", "default").
 				Obj())
 		for _, c := range initialClusterQueues {
-			if err := cache.AddClusterQueue(context.Background(), &c); err != nil {
+			if err := cache.AddClusterQueue(t.Context(), &c); err != nil {
 				return fmt.Errorf("failed adding ClusterQueue: %w", err)
 			}
 		}
@@ -178,7 +178,7 @@ func TestCacheClusterQueueOperations(t *testing.T) {
 					ReclaimWithinCohort: kueue.PreemptionPolicyLowerPriority,
 					WithinClusterQueue:  kueue.PreemptionPolicyLowerPriority,
 				}).Obj()
-				if err := cache.AddClusterQueue(context.Background(), cq); err != nil {
+				if err := cache.AddClusterQueue(t.Context(), cq); err != nil {
 					return fmt.Errorf("failed to add ClusterQueue: %w", err)
 				}
 				return nil
@@ -202,7 +202,7 @@ func TestCacheClusterQueueOperations(t *testing.T) {
 			name: "add ClusterQueue with fair sharing weight",
 			operation: func(cache *Cache) error {
 				cq := utiltesting.MakeClusterQueue("foo").FairWeight(resource.MustParse("2")).Obj()
-				if err := cache.AddClusterQueue(context.Background(), cq); err != nil {
+				if err := cache.AddClusterQueue(t.Context(), cq); err != nil {
 					return fmt.Errorf("failed to add ClusterQueue: %w", err)
 				}
 				return nil
@@ -223,7 +223,7 @@ func TestCacheClusterQueueOperations(t *testing.T) {
 			name: "add flavors after queue capacities",
 			operation: func(cache *Cache) error {
 				for _, c := range initialClusterQueues {
-					if err := cache.AddClusterQueue(context.Background(), &c); err != nil {
+					if err := cache.AddClusterQueue(t.Context(), &c); err != nil {
 						return fmt.Errorf("failed adding ClusterQueue: %w", err)
 					}
 				}
@@ -414,7 +414,7 @@ func TestCacheClusterQueueOperations(t *testing.T) {
 					NamespaceSelector(nil).
 					Obj()
 
-				if err := cache.AddClusterQueue(context.Background(), cq); err != nil {
+				if err := cache.AddClusterQueue(t.Context(), cq); err != nil {
 					return fmt.Errorf("failed adding ClusterQueue: %w", err)
 				}
 
@@ -680,7 +680,7 @@ func TestCacheClusterQueueOperations(t *testing.T) {
 		{
 			name: "Add ClusterQueue with multiple resource groups",
 			operation: func(cache *Cache) error {
-				err := cache.AddClusterQueue(context.Background(),
+				err := cache.AddClusterQueue(t.Context(),
 					utiltesting.MakeClusterQueue("foo").
 						ResourceGroup(
 							*utiltesting.MakeFlavorQuotas("foo").
@@ -717,7 +717,7 @@ func TestCacheClusterQueueOperations(t *testing.T) {
 		{
 			name: "add cluster queue with missing check",
 			operation: func(cache *Cache) error {
-				err := cache.AddClusterQueue(context.Background(),
+				err := cache.AddClusterQueue(t.Context(),
 					utiltesting.MakeClusterQueue("foo").
 						AdmissionChecks("check1", "check2").
 						Obj())
@@ -746,7 +746,7 @@ func TestCacheClusterQueueOperations(t *testing.T) {
 		{
 			name: "add check after queue creation",
 			operation: func(cache *Cache) error {
-				err := cache.AddClusterQueue(context.Background(),
+				err := cache.AddClusterQueue(t.Context(),
 					utiltesting.MakeClusterQueue("foo").
 						AdmissionChecks("check1", "check2").
 						Obj())
@@ -780,7 +780,7 @@ func TestCacheClusterQueueOperations(t *testing.T) {
 			operation: func(cache *Cache) error {
 				cache.AddOrUpdateAdmissionCheck(utiltesting.MakeAdmissionCheck("check1").Active(metav1.ConditionTrue).Obj())
 				cache.AddOrUpdateAdmissionCheck(utiltesting.MakeAdmissionCheck("check2").Active(metav1.ConditionTrue).Obj())
-				err := cache.AddClusterQueue(context.Background(),
+				err := cache.AddClusterQueue(t.Context(),
 					utiltesting.MakeClusterQueue("foo").
 						AdmissionChecks("check1", "check2").
 						Obj())
@@ -813,7 +813,7 @@ func TestCacheClusterQueueOperations(t *testing.T) {
 			operation: func(cache *Cache) error {
 				cache.AddOrUpdateAdmissionCheck(utiltesting.MakeAdmissionCheck("check1").Active(metav1.ConditionTrue).Obj())
 				cache.AddOrUpdateAdmissionCheck(utiltesting.MakeAdmissionCheck("check2").Active(metav1.ConditionTrue).Obj())
-				err := cache.AddClusterQueue(context.Background(),
+				err := cache.AddClusterQueue(t.Context(),
 					utiltesting.MakeClusterQueue("foo").
 						AdmissionChecks("check1", "check2").
 						Obj())
@@ -858,7 +858,7 @@ func TestCacheClusterQueueOperations(t *testing.T) {
 			},
 			operation: func(cache *Cache) error {
 				cache.AddOrUpdateResourceFlavor(utiltesting.MakeResourceFlavor("f1").Obj())
-				err := cache.AddClusterQueue(context.Background(),
+				err := cache.AddClusterQueue(t.Context(),
 					utiltesting.MakeClusterQueue("cq1").
 						ResourceGroup(kueue.FlavorQuotas{
 							Name: "f1",
@@ -973,7 +973,7 @@ func TestCacheClusterQueueOperations(t *testing.T) {
 						},
 					).
 					Obj()
-				return cache.AddClusterQueue(context.Background(), cq)
+				return cache.AddClusterQueue(t.Context(), cq)
 			},
 			wantClusterQueues: map[kueue.ClusterQueueReference]*clusterQueue{
 				"foo": {
@@ -1037,7 +1037,7 @@ func TestCacheClusterQueueOperations(t *testing.T) {
 						},
 					).
 					Obj()
-				return cache.AddClusterQueue(context.Background(), cq)
+				return cache.AddClusterQueue(t.Context(), cq)
 			},
 			wantClusterQueues: map[kueue.ClusterQueueReference]*clusterQueue{
 				"foo": {
@@ -1077,7 +1077,7 @@ func TestCacheClusterQueueOperations(t *testing.T) {
 				cohort := utiltesting.MakeCohort("cohort").Obj()
 				_ = cache.AddOrUpdateCohort(cohort)
 
-				_ = cache.AddClusterQueue(context.Background(),
+				_ = cache.AddClusterQueue(t.Context(),
 					utiltesting.MakeClusterQueue("cq").Cohort("cohort").Obj())
 				cache.DeleteCohort(kueue.CohortReference(cohort.Name))
 				return nil
@@ -1673,7 +1673,7 @@ func TestCacheWorkloadOperations(t *testing.T) {
 			cache := New(cl)
 
 			for _, c := range clusterQueues {
-				if err := cache.AddClusterQueue(context.Background(), &c); err != nil {
+				if err := cache.AddClusterQueue(t.Context(), &c); err != nil {
 					t.Fatalf("Failed adding clusterQueue: %v", err)
 				}
 			}
@@ -2030,7 +2030,7 @@ func TestClusterQueueUsage(t *testing.T) {
 	for name, tc := range cases {
 		t.Run(name, func(t *testing.T) {
 			cache := New(utiltesting.NewFakeClient())
-			ctx := context.Background()
+			ctx := t.Context()
 			err := cache.AddClusterQueue(ctx, tc.clusterQueue)
 			if err != nil {
 				t.Fatalf("Adding ClusterQueue: %v", err)
@@ -2261,7 +2261,7 @@ func TestLocalQueueUsage(t *testing.T) {
 	for name, tc := range cases {
 		t.Run(name, func(t *testing.T) {
 			cache := New(utiltesting.NewFakeClient())
-			ctx := context.Background()
+			ctx := t.Context()
 			if tc.cq != nil {
 				if err := cache.AddClusterQueue(ctx, tc.cq); err != nil {
 					t.Fatalf("Adding ClusterQueue: %v", err)
@@ -2720,7 +2720,7 @@ func TestCacheQueueOperations(t *testing.T) {
 		t.Run(name, func(t *testing.T) {
 			cl := utiltesting.NewFakeClient()
 			cache := New(cl)
-			ctx := context.Background()
+			ctx := t.Context()
 			for i, op := range tc.ops {
 				if err := op(ctx, cl, cache); err != nil {
 					t.Fatalf("Running op %d: %v", i, err)
@@ -2795,7 +2795,7 @@ func TestClusterQueuesUsingFlavor(t *testing.T) {
 			cache.AddOrUpdateResourceFlavor(aarch64Rf)
 
 			for _, cq := range tc.clusterQueues {
-				if err := cache.AddClusterQueue(context.Background(), cq); err != nil {
+				if err := cache.AddClusterQueue(t.Context(), cq); err != nil {
 					t.Errorf("failed to add clusterQueue %s", cq.Name)
 				}
 			}
@@ -2831,7 +2831,7 @@ func TestMatchingClusterQueues(t *testing.T) {
 
 	cache := New(utiltesting.NewFakeClient())
 	for _, cq := range clusterQueues {
-		if err := cache.AddClusterQueue(context.Background(), cq); err != nil {
+		if err := cache.AddClusterQueue(t.Context(), cq); err != nil {
 			t.Errorf("failed to add clusterQueue %s", cq.Name)
 		}
 	}
@@ -2845,7 +2845,7 @@ func TestMatchingClusterQueues(t *testing.T) {
 // TestWaitForPodsReadyCancelled ensures that the WaitForPodsReady call does not block when the context is closed.
 func TestWaitForPodsReadyCancelled(t *testing.T) {
 	cache := New(utiltesting.NewFakeClient(), WithPodsReadyTracking(true))
-	ctx, cancel := context.WithCancel(context.Background())
+	ctx, cancel := context.WithCancel(t.Context())
 	defer cancel()
 	log := ctrl.LoggerFrom(ctx)
 
@@ -3103,7 +3103,7 @@ func TestCachePodsReadyForAllAdmittedWorkloads(t *testing.T) {
 	for _, tc := range tests {
 		t.Run(tc.name, func(t *testing.T) {
 			cache := New(cl, WithPodsReadyTracking(true))
-			ctx := context.Background()
+			ctx := t.Context()
 			log := ctrl.LoggerFrom(ctx)
 
 			for _, c := range clusterQueues {
@@ -3316,7 +3316,7 @@ func TestClusterQueuesUsingAdmissionChecks(t *testing.T) {
 			}
 
 			for _, cq := range tc.clusterQueues {
-				if err := cache.AddClusterQueue(context.Background(), cq); err != nil {
+				if err := cache.AddClusterQueue(t.Context(), cq); err != nil {
 					t.Errorf("failed to add clusterQueue %s", cq.Name)
 				}
 			}
@@ -3431,7 +3431,7 @@ func TestClusterQueueReadiness(t *testing.T) {
 				cache.AddOrUpdateAdmissionCheck(ac)
 			}
 			for _, cq := range tc.clusterQueues {
-				if err := cache.AddClusterQueue(context.Background(), cq); err != nil {
+				if err := cache.AddClusterQueue(t.Context(), cq); err != nil {
 					t.Errorf("failed to add clusterQueue %q: %v", cq.Name, err)
 				}
 			}
@@ -3488,7 +3488,7 @@ func TestCohortCycles(t *testing.T) {
 	})
 	t.Run("clusterqueue add and update return error when cohort has cycle", func(t *testing.T) {
 		cache := New(utiltesting.NewFakeClient())
-		ctx := context.Background()
+		ctx := t.Context()
 		cohortA := utiltesting.MakeCohort("cohort-a").Parent("cohort-b").Obj()
 		if err := cache.AddOrUpdateCohort(cohortA); err != nil {
 			t.Fatal("Expected success as no cycle yet")
@@ -3526,7 +3526,7 @@ func TestCohortCycles(t *testing.T) {
 
 	t.Run("clusterqueue leaving cohort with cycle successfully updates new cohort", func(t *testing.T) {
 		cache := New(utiltesting.NewFakeClient())
-		ctx := context.Background()
+		ctx := t.Context()
 		cycleCohort := utiltesting.MakeCohort("cycle").Parent("cycle").Obj()
 		if err := cache.AddOrUpdateCohort(cycleCohort); err == nil {
 			t.Fatal("Expected failure")
@@ -3570,7 +3570,7 @@ func TestCohortCycles(t *testing.T) {
 
 	t.Run("clusterqueue joining cohort with cycle successfully updates old cohort", func(t *testing.T) {
 		cache := New(utiltesting.NewFakeClient())
-		ctx := context.Background()
+		ctx := t.Context()
 		cycleCohort := utiltesting.MakeCohort("cycle").Parent("cycle").Obj()
 		if err := cache.AddOrUpdateCohort(cycleCohort); err == nil {
 			t.Fatal("Expected failure")
diff --git a/pkg/cache/resource_node_test.go b/pkg/cache/resource_node_test.go
index 3b5454895..f99062d9e 100644
--- a/pkg/cache/resource_node_test.go
+++ b/pkg/cache/resource_node_test.go
@@ -17,7 +17,6 @@ limitations under the License.
 package cache
 
 import (
-	"context"
 	"testing"
 
 	"github.com/google/go-cmp/cmp"
@@ -46,10 +45,10 @@ func TestCohortLendable(t *testing.T) {
 		).Cohort("test-cohort").
 		ClusterQueue
 
-	if err := cache.AddClusterQueue(context.Background(), &cq1); err != nil {
+	if err := cache.AddClusterQueue(t.Context(), &cq1); err != nil {
 		t.Fatal("Failed to add CQ to cache", err)
 	}
-	if err := cache.AddClusterQueue(context.Background(), &cq2); err != nil {
+	if err := cache.AddClusterQueue(t.Context(), &cq2); err != nil {
 		t.Fatal("Failed to add CQ to cache", err)
 	}
 
diff --git a/pkg/cache/resource_test.go b/pkg/cache/resource_test.go
index b9dda5131..e481148b7 100644
--- a/pkg/cache/resource_test.go
+++ b/pkg/cache/resource_test.go
@@ -17,7 +17,6 @@ limitations under the License.
 package cache
 
 import (
-	"context"
 	"testing"
 
 	"github.com/google/go-cmp/cmp"
@@ -362,7 +361,7 @@ func TestAvailable(t *testing.T) {
 
 	for name, tc := range cases {
 		t.Run(name, func(t *testing.T) {
-			ctx := context.Background()
+			ctx := t.Context()
 			cache := New(utiltesting.NewFakeClient())
 			cache.AddOrUpdateResourceFlavor(utiltesting.MakeResourceFlavor("red").Obj())
 			cache.AddOrUpdateResourceFlavor(utiltesting.MakeResourceFlavor("blue").Obj())
diff --git a/pkg/cache/snapshot_test.go b/pkg/cache/snapshot_test.go
index 43fcd5f87..b4b975664 100644
--- a/pkg/cache/snapshot_test.go
+++ b/pkg/cache/snapshot_test.go
@@ -17,7 +17,6 @@ limitations under the License.
 package cache
 
 import (
-	"context"
 	"testing"
 
 	"github.com/google/go-cmp/cmp"
@@ -988,7 +987,7 @@ func TestSnapshotAddRemoveWorkload(t *testing.T) {
 			Obj(),
 	}
 
-	ctx := context.Background()
+	ctx := t.Context()
 	cl := utiltesting.NewClientBuilder().WithLists(&kueue.WorkloadList{Items: workloads}).Build()
 
 	cqCache := New(cl)
@@ -1282,7 +1281,7 @@ func TestSnapshotAddRemoveWorkloadWithLendingLimit(t *testing.T) {
 			Obj(),
 	}
 
-	ctx := context.Background()
+	ctx := t.Context()
 	cl := utiltesting.NewClientBuilder().WithLists(&kueue.WorkloadList{Items: workloads}).Build()
 
 	cqCache := New(cl)
diff --git a/pkg/controller/admissionchecks/multikueue/admissioncheck_test.go b/pkg/controller/admissionchecks/multikueue/admissioncheck_test.go
index 7d2f294c0..2d776a371 100644
--- a/pkg/controller/admissionchecks/multikueue/admissioncheck_test.go
+++ b/pkg/controller/admissionchecks/multikueue/admissioncheck_test.go
@@ -280,7 +280,7 @@ func TestReconcile(t *testing.T) {
 			if tc.acValidationRulesEnabled {
 				features.SetFeatureGateDuringTest(t, features.AdmissionCheckValidationRules, true)
 			}
-			builder, ctx := getClientBuilder()
+			builder := getClientBuilder(t.Context())
 
 			builder = builder.WithLists(
 				&kueue.AdmissionCheckList{Items: tc.checks},
@@ -297,13 +297,13 @@ func TestReconcile(t *testing.T) {
 			helper, _ := newMultiKueueStoreHelper(c)
 			reconciler := newACReconciler(c, helper)
 
-			_, gotErr := reconciler.Reconcile(ctx, reconcile.Request{NamespacedName: types.NamespacedName{Name: tc.reconcileFor}})
+			_, gotErr := reconciler.Reconcile(t.Context(), reconcile.Request{NamespacedName: types.NamespacedName{Name: tc.reconcileFor}})
 			if diff := cmp.Diff(tc.wantError, gotErr); diff != "" {
 				t.Errorf("unexpected error (-want/+got):\n%s", diff)
 			}
 
 			checks := &kueue.AdmissionCheckList{}
-			listErr := c.List(ctx, checks)
+			listErr := c.List(t.Context(), checks)
 
 			if listErr != nil {
 				t.Errorf("unexpected list checks error: %s", listErr)
diff --git a/pkg/controller/admissionchecks/multikueue/fswatch_test.go b/pkg/controller/admissionchecks/multikueue/fswatch_test.go
index 98e971582..28b56bcbd 100644
--- a/pkg/controller/admissionchecks/multikueue/fswatch_test.go
+++ b/pkg/controller/admissionchecks/multikueue/fswatch_test.go
@@ -143,7 +143,7 @@ func TestFSWatch(t *testing.T) {
 					t.Fatalf("unexpected prepare error: %s", err)
 				}
 			}
-			ctx, cancel := context.WithTimeout(context.Background(), time.Second)
+			ctx, cancel := context.WithTimeout(t.Context(), time.Second)
 			watcher := newKubeConfigFSWatcher()
 
 			// start the recorder
@@ -193,7 +193,7 @@ func TestFSWatch(t *testing.T) {
 }
 
 func TestFSWatchAddRm(t *testing.T) {
-	ctx, cancel := context.WithCancel(context.Background())
+	ctx, cancel := context.WithCancel(t.Context())
 	defer cancel()
 	basePath := t.TempDir()
 	f1Path := filepath.Join(basePath, "file.one")
diff --git a/pkg/controller/admissionchecks/multikueue/indexer_test.go b/pkg/controller/admissionchecks/multikueue/indexer_test.go
index 082dd203e..1717b7d43 100644
--- a/pkg/controller/admissionchecks/multikueue/indexer_test.go
+++ b/pkg/controller/admissionchecks/multikueue/indexer_test.go
@@ -38,7 +38,7 @@ const (
 	TestNamespace = "ns"
 )
 
-func getClientBuilder() (*fake.ClientBuilder, context.Context) {
+func getClientBuilder(ctx context.Context) *fake.ClientBuilder {
 	scheme := runtime.NewScheme()
 	utilruntime.Must(clientgoscheme.AddToScheme(scheme))
 	utilruntime.Must(kueue.AddToScheme(scheme))
@@ -51,10 +51,9 @@ func getClientBuilder() (*fake.ClientBuilder, context.Context) {
 		return nil
 	}))
 
-	ctx := context.Background()
 	builder := fake.NewClientBuilder().WithScheme(scheme).WithObjects(utiltesting.MakeNamespace(TestNamespace))
 	_ = SetupIndexer(ctx, utiltesting.AsIndexer(builder), TestNamespace)
-	return builder, ctx
+	return builder
 }
 
 func TestListMultiKueueClustersUsingKubeConfig(t *testing.T) {
@@ -91,17 +90,17 @@ func TestListMultiKueueClustersUsingKubeConfig(t *testing.T) {
 	}
 	for name, tc := range cases {
 		t.Run(name, func(t *testing.T) {
-			builder, ctx := getClientBuilder()
+			builder := getClientBuilder(t.Context())
 			k8sclient := builder.Build()
 			for _, req := range tc.clusters {
-				if err := k8sclient.Create(ctx, req); err != nil {
+				if err := k8sclient.Create(t.Context(), req); err != nil {
 					t.Fatalf("Unable to create %q cluster: %v", client.ObjectKeyFromObject(req), err)
 				}
 			}
 
 			lst := &kueue.MultiKueueClusterList{}
 
-			gotListErr := k8sclient.List(ctx, lst, tc.filter)
+			gotListErr := k8sclient.List(t.Context(), lst, tc.filter)
 			if diff := cmp.Diff(tc.wantListError, gotListErr); diff != "" {
 				t.Errorf("unexpected list error (-want/+got):\n%s", diff)
 			}
@@ -148,17 +147,17 @@ func TestListMultiKueueConfigsUsingMultiKueueClusters(t *testing.T) {
 	}
 	for name, tc := range cases {
 		t.Run(name, func(t *testing.T) {
-			builder, ctx := getClientBuilder()
+			builder := getClientBuilder(t.Context())
 			k8sclient := builder.Build()
 			for _, config := range tc.configs {
-				if err := k8sclient.Create(ctx, config); err != nil {
+				if err := k8sclient.Create(t.Context(), config); err != nil {
 					t.Fatalf("Unable to create %q config: %v", client.ObjectKeyFromObject(config), err)
 				}
 			}
 
 			lst := &kueue.MultiKueueConfigList{}
 
-			gotListErr := k8sclient.List(ctx, lst, tc.filter)
+			gotListErr := k8sclient.List(t.Context(), lst, tc.filter)
 			if diff := cmp.Diff(tc.wantListError, gotListErr); diff != "" {
 				t.Errorf("unexpected list error (-want/+got):\n%s", diff)
 			}
diff --git a/pkg/controller/admissionchecks/multikueue/multikueuecluster_test.go b/pkg/controller/admissionchecks/multikueue/multikueuecluster_test.go
index 767c4696a..66f0bf197 100644
--- a/pkg/controller/admissionchecks/multikueue/multikueuecluster_test.go
+++ b/pkg/controller/admissionchecks/multikueue/multikueuecluster_test.go
@@ -48,31 +48,33 @@ var (
 	errCannotWatch   = errors.New("client cannot watch")
 )
 
-func fakeClientBuilder(kubeconfig []byte, _ client.Options) (client.WithWatch, error) {
-	if string(kubeconfig) == "invalid" {
-		return nil, errInvalidConfig
+func fakeClientBuilder(ctx context.Context) func([]byte, client.Options) (client.WithWatch, error) {
+	return func(kubeconfig []byte, _ client.Options) (client.WithWatch, error) {
+		if string(kubeconfig) == "invalid" {
+			return nil, errInvalidConfig
+		}
+		b := getClientBuilder(ctx)
+		b = b.WithInterceptorFuncs(interceptor.Funcs{
+			Watch: func(ctx context.Context, client client.WithWatch, obj client.ObjectList, opts ...client.ListOption) (watch.Interface, error) {
+				if string(kubeconfig) == "nowatch" {
+					return nil, errCannotWatch
+				}
+				return client.Watch(ctx, obj, opts...)
+			},
+		})
+		return b.Build(), nil
 	}
-	b, _ := getClientBuilder()
-	b = b.WithInterceptorFuncs(interceptor.Funcs{
-		Watch: func(ctx context.Context, client client.WithWatch, obj client.ObjectList, opts ...client.ListOption) (watch.Interface, error) {
-			if string(kubeconfig) == "nowatch" {
-				return nil, errCannotWatch
-			}
-			return client.Watch(ctx, obj, opts...)
-		},
-	})
-	return b.Build(), nil
 }
 
-func newTestClient(config string, watchCancel func()) *remoteClient {
-	b, _ := getClientBuilder()
+func newTestClient(ctx context.Context, config string, watchCancel func()) *remoteClient {
+	b := getClientBuilder(ctx)
 	localClient := b.Build()
 	ret := &remoteClient{
 		kubeconfig:  []byte(config),
 		localClient: localClient,
 		watchCancel: watchCancel,
 
-		builderOverride: fakeClientBuilder,
+		builderOverride: fakeClientBuilder(ctx),
 	}
 	return ret
 }
@@ -146,7 +148,7 @@ func TestUpdateConfig(t *testing.T) {
 				makeTestSecret("worker1", "worker1 kubeconfig"),
 			},
 			remoteClients: map[string]*remoteClient{
-				"worker1": newTestClient("worker1 old kubeconfig", cancelCalled),
+				"worker1": newTestClient(t.Context(), "worker1 old kubeconfig", cancelCalled),
 			},
 			wantClusters: []kueue.MultiKueueCluster{
 				*utiltesting.MakeMultiKueueCluster("worker1").
@@ -171,7 +173,7 @@ func TestUpdateConfig(t *testing.T) {
 					Obj(),
 			},
 			remoteClients: map[string]*remoteClient{
-				"worker1": newTestClient("worker1 old kubeconfig", cancelCalled),
+				"worker1": newTestClient(t.Context(), "worker1 old kubeconfig", cancelCalled),
 			},
 			wantClusters: []kueue.MultiKueueCluster{
 				*utiltesting.MakeMultiKueueCluster("worker1").
@@ -199,10 +201,10 @@ func TestUpdateConfig(t *testing.T) {
 				makeTestSecret("worker1", "invalid"),
 			},
 			remoteClients: map[string]*remoteClient{
-				"worker1": newTestClient("worker1 old kubeconfig", cancelCalled),
+				"worker1": newTestClient(t.Context(), "worker1 old kubeconfig", cancelCalled),
 			},
 			wantRemoteClients: map[string]*remoteClient{
-				"worker1": newTestClient("invalid", nil),
+				"worker1": newTestClient(t.Context(), "invalid", nil),
 			},
 			wantClusters: []kueue.MultiKueueCluster{
 				*utiltesting.MakeMultiKueueCluster("worker1").
@@ -222,7 +224,7 @@ func TestUpdateConfig(t *testing.T) {
 					Obj(),
 			},
 			remoteClients: map[string]*remoteClient{
-				"worker1": newTestClient("worker1 old kubeconfig", cancelCalled),
+				"worker1": newTestClient(t.Context(), "worker1 old kubeconfig", cancelCalled),
 			},
 			wantClusters: []kueue.MultiKueueCluster{
 				*utiltesting.MakeMultiKueueCluster("worker1").
@@ -242,8 +244,8 @@ func TestUpdateConfig(t *testing.T) {
 					Obj(),
 			},
 			remoteClients: map[string]*remoteClient{
-				"worker1": newTestClient("worker1 kubeconfig", cancelCalled),
-				"worker2": newTestClient("worker2 kubeconfig", cancelCalled),
+				"worker1": newTestClient(t.Context(), "worker1 kubeconfig", cancelCalled),
+				"worker2": newTestClient(t.Context(), "worker2 kubeconfig", cancelCalled),
 			},
 			wantClusters: []kueue.MultiKueueCluster{
 				*utiltesting.MakeMultiKueueCluster("worker1").
@@ -270,10 +272,10 @@ func TestUpdateConfig(t *testing.T) {
 				makeTestSecret("worker1", "nowatch"),
 			},
 			remoteClients: map[string]*remoteClient{
-				"worker1": newTestClient("worker1 old kubeconfig", cancelCalled),
+				"worker1": newTestClient(t.Context(), "worker1 old kubeconfig", cancelCalled),
 			},
 			wantRemoteClients: map[string]*remoteClient{
-				"worker1": setReconnectState(newTestClient("nowatch", nil), 1),
+				"worker1": setReconnectState(newTestClient(t.Context(), "nowatch", nil), 1),
 			},
 			wantClusters: []kueue.MultiKueueCluster{
 				*utiltesting.MakeMultiKueueCluster("worker1").
@@ -298,10 +300,10 @@ func TestUpdateConfig(t *testing.T) {
 				makeTestSecret("worker1", "nowatch"),
 			},
 			remoteClients: map[string]*remoteClient{
-				"worker1": setReconnectState(newTestClient("nowatch", cancelCalled), 2),
+				"worker1": setReconnectState(newTestClient(t.Context(), "nowatch", cancelCalled), 2),
 			},
 			wantRemoteClients: map[string]*remoteClient{
-				"worker1": setReconnectState(newTestClient("nowatch", nil), 3),
+				"worker1": setReconnectState(newTestClient(t.Context(), "nowatch", nil), 3),
 			},
 			wantClusters: []kueue.MultiKueueCluster{
 				*utiltesting.MakeMultiKueueCluster("worker1").
@@ -326,10 +328,10 @@ func TestUpdateConfig(t *testing.T) {
 				makeTestSecret("worker1", "good config"),
 			},
 			remoteClients: map[string]*remoteClient{
-				"worker1": setReconnectState(newTestClient("nowatch", cancelCalled), 5),
+				"worker1": setReconnectState(newTestClient(t.Context(), "nowatch", cancelCalled), 5),
 			},
 			wantRemoteClients: map[string]*remoteClient{
-				"worker1": newTestClient("good config", nil),
+				"worker1": newTestClient(t.Context(), "good config", nil),
 			},
 			wantClusters: []kueue.MultiKueueCluster{
 				*utiltesting.MakeMultiKueueCluster("worker1").
@@ -353,10 +355,10 @@ func TestUpdateConfig(t *testing.T) {
 				makeTestSecret("worker1", "invalid"),
 			},
 			remoteClients: map[string]*remoteClient{
-				"worker1": setReconnectState(newTestClient("nowatch", cancelCalled), 5),
+				"worker1": setReconnectState(newTestClient(t.Context(), "nowatch", cancelCalled), 5),
 			},
 			wantRemoteClients: map[string]*remoteClient{
-				"worker1": newTestClient("invalid", nil),
+				"worker1": newTestClient(t.Context(), "invalid", nil),
 			},
 			wantClusters: []kueue.MultiKueueCluster{
 				*utiltesting.MakeMultiKueueCluster("worker1").
@@ -371,7 +373,7 @@ func TestUpdateConfig(t *testing.T) {
 
 	for name, tc := range cases {
 		t.Run(name, func(t *testing.T) {
-			builder, ctx := getClientBuilder()
+			builder := getClientBuilder(t.Context())
 			builder = builder.WithLists(&kueue.MultiKueueClusterList{Items: tc.clusters})
 			builder = builder.WithLists(&corev1.SecretList{Items: tc.secrets})
 			builder = builder.WithStatusSubresource(slices.Map(tc.clusters, func(c *kueue.MultiKueueCluster) client.Object { return c })...)
@@ -380,15 +382,15 @@ func TestUpdateConfig(t *testing.T) {
 			adapters, _ := jobframework.GetMultiKueueAdapters(sets.New("batch/job"))
 			reconciler := newClustersReconciler(c, TestNamespace, 0, defaultOrigin, nil, adapters)
 
-			reconciler.rootContext = ctx
+			reconciler.rootContext = t.Context()
 
 			if len(tc.remoteClients) > 0 {
 				reconciler.remoteClients = tc.remoteClients
 			}
-			reconciler.builderOverride = fakeClientBuilder
+			reconciler.builderOverride = fakeClientBuilder(t.Context())
 
 			cancelCalledCount = 0
-			res, gotErr := reconciler.Reconcile(ctx, reconcile.Request{NamespacedName: types.NamespacedName{Name: tc.reconcileFor}})
+			res, gotErr := reconciler.Reconcile(t.Context(), reconcile.Request{NamespacedName: types.NamespacedName{Name: tc.reconcileFor}})
 			if gotErr != nil {
 				t.Errorf("unexpected reconcile error: %s", gotErr)
 			}
@@ -402,7 +404,7 @@ func TestUpdateConfig(t *testing.T) {
 			}
 
 			lst := &kueue.MultiKueueClusterList{}
-			gotErr = c.List(ctx, lst)
+			gotErr = c.List(t.Context(), lst)
 			if gotErr != nil {
 				t.Errorf("unexpected list clusters error: %s", gotErr)
 			}
@@ -530,11 +532,11 @@ func TestRemoteClientGC(t *testing.T) {
 
 	for name, tc := range cases {
 		t.Run(name, func(t *testing.T) {
-			manageBuilder, ctx := getClientBuilder()
+			manageBuilder := getClientBuilder(t.Context())
 			manageBuilder = manageBuilder.WithLists(&kueue.WorkloadList{Items: tc.managersWorkloads}, &batchv1.JobList{Items: tc.managersJobs})
 			managerClient := manageBuilder.Build()
 
-			worker1Builder, _ := getClientBuilder()
+			worker1Builder := getClientBuilder(t.Context())
 			worker1Builder = worker1Builder.WithLists(&kueue.WorkloadList{Items: tc.workersWorkloads}, &batchv1.JobList{Items: tc.workersJobs})
 			worker1Client := worker1Builder.Build()
 
@@ -543,10 +545,10 @@ func TestRemoteClientGC(t *testing.T) {
 			w1remoteClient.client = worker1Client
 			w1remoteClient.connecting.Store(false)
 
-			w1remoteClient.runGC(ctx)
+			w1remoteClient.runGC(t.Context())
 
 			gotWorker1Workloads := &kueue.WorkloadList{}
-			err := worker1Client.List(ctx, gotWorker1Workloads)
+			err := worker1Client.List(t.Context(), gotWorker1Workloads)
 			if err != nil {
 				t.Error("unexpected list worker's workloads error")
 			}
@@ -556,7 +558,7 @@ func TestRemoteClientGC(t *testing.T) {
 			}
 
 			gotWorker1Job := &batchv1.JobList{}
-			err = worker1Client.List(ctx, gotWorker1Job)
+			err = worker1Client.List(t.Context(), gotWorker1Job)
 			if err != nil {
 				t.Error("unexpected list worker's jobs error")
 			}
diff --git a/pkg/controller/admissionchecks/multikueue/workload_test.go b/pkg/controller/admissionchecks/multikueue/workload_test.go
index d896db867..38569941f 100644
--- a/pkg/controller/admissionchecks/multikueue/workload_test.go
+++ b/pkg/controller/admissionchecks/multikueue/workload_test.go
@@ -1003,7 +1003,7 @@ func TestWlReconcile(t *testing.T) {
 	for name, tc := range cases {
 		t.Run(name, func(t *testing.T) {
 			features.SetFeatureGateDuringTest(t, features.MultiKueueBatchJobWithManagedBy, !tc.withoutJobManagedBy)
-			managerBuilder, ctx := getClientBuilder()
+			managerBuilder := getClientBuilder(t.Context())
 			managerBuilder = managerBuilder.WithInterceptorFuncs(interceptor.Funcs{SubResourcePatch: utiltesting.TreatSSAAsStrategicMerge})
 
 			workerClusters := []string{"worker1"}
@@ -1024,7 +1024,7 @@ func TestWlReconcile(t *testing.T) {
 			adapters, _ := jobframework.GetMultiKueueAdapters(sets.New("batch/job"))
 			cRec := newClustersReconciler(managerClient, TestNamespace, 0, defaultOrigin, nil, adapters)
 
-			worker1Builder, _ := getClientBuilder()
+			worker1Builder := getClientBuilder(t.Context())
 			worker1Builder = worker1Builder.WithLists(&kueue.WorkloadList{Items: tc.worker1Workloads}, &batchv1.JobList{Items: tc.worker1Jobs})
 			worker1Client := worker1Builder.Build()
 
@@ -1035,7 +1035,7 @@ func TestWlReconcile(t *testing.T) {
 
 			var worker2Client client.WithWatch
 			if tc.useSecondWorker {
-				worker2Builder, _ := getClientBuilder()
+				worker2Builder := getClientBuilder(t.Context())
 				worker2Builder = worker2Builder.WithLists(&kueue.WorkloadList{Items: tc.worker2Workloads}, &batchv1.JobList{Items: tc.worker2Jobs})
 				worker2Builder = worker2Builder.WithInterceptorFuncs(interceptor.Funcs{
 					Get: func(ctx context.Context, c client.WithWatch, key client.ObjectKey, obj client.Object, opts ...client.GetOption) error {
@@ -1076,13 +1076,13 @@ func TestWlReconcile(t *testing.T) {
 				})
 			}
 
-			_, gotErr := reconciler.Reconcile(ctx, reconcile.Request{NamespacedName: types.NamespacedName{Name: tc.reconcileFor, Namespace: TestNamespace}})
+			_, gotErr := reconciler.Reconcile(t.Context(), reconcile.Request{NamespacedName: types.NamespacedName{Name: tc.reconcileFor, Namespace: TestNamespace}})
 			if diff := cmp.Diff(tc.wantError, gotErr, cmpopts.EquateErrors()); diff != "" {
 				t.Errorf("unexpected error (-want/+got):\n%s", diff)
 			}
 
 			gotManagersWorkloads := &kueue.WorkloadList{}
-			if err := managerClient.List(ctx, gotManagersWorkloads); err != nil {
+			if err := managerClient.List(t.Context(), gotManagersWorkloads); err != nil {
 				t.Errorf("unexpected list manager's workloads error: %s", err)
 			} else {
 				if diff := cmp.Diff(tc.wantManagersWorkloads, gotManagersWorkloads.Items, objCheckOpts...); diff != "" {
@@ -1091,7 +1091,7 @@ func TestWlReconcile(t *testing.T) {
 			}
 
 			gotWorker1Workloads := &kueue.WorkloadList{}
-			if err := worker1Client.List(ctx, gotWorker1Workloads); err != nil {
+			if err := worker1Client.List(t.Context(), gotWorker1Workloads); err != nil {
 				t.Errorf("unexpected list worker's workloads error: %s", err)
 			} else {
 				if diff := cmp.Diff(tc.wantWorker1Workloads, gotWorker1Workloads.Items, objCheckOpts...); diff != "" {
@@ -1100,7 +1100,7 @@ func TestWlReconcile(t *testing.T) {
 			}
 
 			gotManagersJobs := &batchv1.JobList{}
-			if err := managerClient.List(ctx, gotManagersJobs); err != nil {
+			if err := managerClient.List(t.Context(), gotManagersJobs); err != nil {
 				t.Errorf("unexpected list manager's jobs error %s", err)
 			} else {
 				if diff := cmp.Diff(tc.wantManagersJobs, gotManagersJobs.Items, objCheckOpts...); diff != "" {
@@ -1109,7 +1109,7 @@ func TestWlReconcile(t *testing.T) {
 			}
 
 			gotWorker1Jobs := &batchv1.JobList{}
-			if err := worker1Client.List(ctx, gotWorker1Jobs); err != nil {
+			if err := worker1Client.List(t.Context(), gotWorker1Jobs); err != nil {
 				t.Error("unexpected list worker's jobs error")
 			} else {
 				if diff := cmp.Diff(tc.wantWorker1Jobs, gotWorker1Jobs.Items, objCheckOpts...); diff != "" {
@@ -1119,7 +1119,7 @@ func TestWlReconcile(t *testing.T) {
 
 			if tc.useSecondWorker {
 				gotWorker2Workloads := &kueue.WorkloadList{}
-				if err := worker2Client.List(ctx, gotWorker2Workloads); err != nil {
+				if err := worker2Client.List(t.Context(), gotWorker2Workloads); err != nil {
 					t.Errorf("unexpected list worker2 workloads error: %s", err)
 				} else {
 					if diff := cmp.Diff(tc.wantWorker2Workloads, gotWorker2Workloads.Items, objCheckOpts...); diff != "" {
@@ -1128,7 +1128,7 @@ func TestWlReconcile(t *testing.T) {
 				}
 
 				gotWorker2Jobs := &batchv1.JobList{}
-				if err := worker2Client.List(ctx, gotWorker2Jobs); err != nil {
+				if err := worker2Client.List(t.Context(), gotWorker2Jobs); err != nil {
 					t.Errorf("unexpected list worker2 jobs error: %s", err)
 				} else {
 					if diff := cmp.Diff(tc.wantWorker2Jobs, gotWorker2Jobs.Items, objCheckOpts...); diff != "" {
diff --git a/pkg/controller/admissionchecks/provisioning/admissioncheck_reconciler_test.go b/pkg/controller/admissionchecks/provisioning/admissioncheck_reconciler_test.go
index 09b94c573..80705fb55 100644
--- a/pkg/controller/admissionchecks/provisioning/admissioncheck_reconciler_test.go
+++ b/pkg/controller/admissionchecks/provisioning/admissioncheck_reconciler_test.go
@@ -114,7 +114,7 @@ func TestReconcileAdmissionCheck(t *testing.T) {
 
 	for name, tc := range cases {
 		t.Run(name, func(t *testing.T) {
-			builder, ctx := getClientBuilder()
+			builder, ctx := getClientBuilder(t.Context())
 
 			builder = builder.WithObjects(tc.check)
 			builder = builder.WithStatusSubresource(tc.check)
diff --git a/pkg/controller/admissionchecks/provisioning/controller_test.go b/pkg/controller/admissionchecks/provisioning/controller_test.go
index 22ba38943..4cfa77155 100644
--- a/pkg/controller/admissionchecks/provisioning/controller_test.go
+++ b/pkg/controller/admissionchecks/provisioning/controller_test.go
@@ -1256,7 +1256,7 @@ func TestReconcile(t *testing.T) {
 				interceptorFuncs.Create = tc.interceptorFuncsCreate
 			}
 
-			builder, ctx := getClientBuilder()
+			builder, ctx := getClientBuilder(t.Context())
 			builder = builder.WithInterceptorFuncs(interceptorFuncs)
 			builder = builder.WithObjects(tc.workload)
 			builder = builder.WithStatusSubresource(tc.workload)
@@ -1441,7 +1441,7 @@ func TestActiveOrLastPRForChecks(t *testing.T) {
 				baseCheck.Name: baseConfig.DeepCopy(),
 			}
 
-			builder, ctx := getClientBuilder()
+			builder, ctx := getClientBuilder(t.Context())
 
 			builder = builder.WithObjects(workload)
 			builder = builder.WithStatusSubresource(workload)
diff --git a/pkg/controller/admissionchecks/provisioning/indexer_test.go b/pkg/controller/admissionchecks/provisioning/indexer_test.go
index 9b964b7c5..4f6eb2e22 100644
--- a/pkg/controller/admissionchecks/provisioning/indexer_test.go
+++ b/pkg/controller/admissionchecks/provisioning/indexer_test.go
@@ -39,13 +39,12 @@ const (
 	TestNamespace = "ns"
 )
 
-func getClientBuilder() (*fake.ClientBuilder, context.Context) {
+func getClientBuilder(ctx context.Context) (*fake.ClientBuilder, context.Context) {
 	scheme := runtime.NewScheme()
 	utilruntime.Must(clientgoscheme.AddToScheme(scheme))
 	utilruntime.Must(kueue.AddToScheme(scheme))
 	utilruntime.Must(autoscaling.AddToScheme(scheme))
 
-	ctx := context.Background()
 	builder := fake.NewClientBuilder().WithScheme(scheme).WithObjects(utiltesting.MakeNamespace(TestNamespace))
 	_ = SetupIndexer(ctx, utiltesting.AsIndexer(builder))
 	return builder, ctx
@@ -132,7 +131,7 @@ func TestIndexProvisioningRequests(t *testing.T) {
 	}
 	for name, tc := range cases {
 		t.Run(name, func(t *testing.T) {
-			builder, ctx := getClientBuilder()
+			builder, ctx := getClientBuilder(t.Context())
 			k8sclient := builder.Build()
 			for _, req := range tc.requests {
 				if err := k8sclient.Create(ctx, req); err != nil {
@@ -242,7 +241,7 @@ func TestIndexWorkload(t *testing.T) {
 	}
 	for name, tc := range cases {
 		t.Run(name, func(t *testing.T) {
-			builder, ctx := getClientBuilder()
+			builder, ctx := getClientBuilder(t.Context())
 			k8sclient := builder.Build()
 			for _, wl := range tc.workloads {
 				if err := k8sclient.Create(ctx, wl); err != nil {
@@ -338,7 +337,7 @@ func TestIndexAdmissionChecks(t *testing.T) {
 	}
 	for name, tc := range cases {
 		t.Run(name, func(t *testing.T) {
-			builder, ctx := getClientBuilder()
+			builder, ctx := getClientBuilder(t.Context())
 			k8sclient := builder.Build()
 			for _, req := range tc.checks {
 				if err := k8sclient.Create(ctx, req); err != nil {
diff --git a/pkg/controller/core/clusterqueue_controller_test.go b/pkg/controller/core/clusterqueue_controller_test.go
index f6db2a06f..08f8836f9 100644
--- a/pkg/controller/core/clusterqueue_controller_test.go
+++ b/pkg/controller/core/clusterqueue_controller_test.go
@@ -568,7 +568,7 @@ func TestClusterQueuePendingWorkloadsStatus(t *testing.T) {
 				QueueingStrategy(kueue.StrictFIFO).Obj()
 			lq := utiltesting.MakeLocalQueue(lqName, "").
 				ClusterQueue(cqName).Obj()
-			ctx := context.Background()
+			ctx := t.Context()
 
 			cl := utiltesting.NewClientBuilder().WithLists(defaultWls).WithObjects(lq, cq).WithStatusSubresource(lq, cq).
 				Build()
diff --git a/pkg/controller/core/cohort_controller_test.go b/pkg/controller/core/cohort_controller_test.go
index ccaaf801e..9a0d6b89b 100644
--- a/pkg/controller/core/cohort_controller_test.go
+++ b/pkg/controller/core/cohort_controller_test.go
@@ -36,7 +36,7 @@ import (
 
 func TestCohortReconcileCohortNotFoundDelete(t *testing.T) {
 	cl := utiltesting.NewClientBuilder().Build()
-	ctx := context.Background()
+	ctx := t.Context()
 	cache := cache.New(cl)
 	qManager := queue.NewManager(cl, cache)
 	reconciler := NewCohortReconciler(cl, cache, qManager)
@@ -71,7 +71,7 @@ func TestCohortReconcileCohortNotFoundDelete(t *testing.T) {
 func TestCohortReconcileCohortNotFoundIdempotentDelete(t *testing.T) {
 	cl := utiltesting.NewClientBuilder().
 		Build()
-	ctx := context.Background()
+	ctx := t.Context()
 	cache := cache.New(cl)
 	qManager := queue.NewManager(cl, cache)
 	reconciler := NewCohortReconciler(cl, cache, qManager)
@@ -108,7 +108,7 @@ func TestCohortReconcileCycleNoError(t *testing.T) {
 		WithObjects(cohortA, cohortB).
 		WithStatusSubresource(&kueue.Cohort{}).
 		Build()
-	ctx := context.Background()
+	ctx := t.Context()
 	cache := cache.New(cl)
 	qManager := queue.NewManager(cl, cache)
 	reconciler := NewCohortReconciler(cl, cache, qManager)
@@ -146,7 +146,7 @@ func TestCohortReconcileCycleNoError(t *testing.T) {
 }
 
 func TestCohortReconcileErrorOtherThanNotFoundNotDeleted(t *testing.T) {
-	ctx := context.Background()
+	ctx := t.Context()
 	funcs := interceptor.Funcs{
 		Get: func(ctx context.Context, client client.WithWatch, key client.ObjectKey, obj client.Object, opts ...client.GetOption) error {
 			return errors.New("error")
@@ -185,7 +185,7 @@ func TestCohortReconcileErrorOtherThanNotFoundNotDeleted(t *testing.T) {
 }
 
 func TestCohortReconcileLifecycle(t *testing.T) {
-	ctx := context.Background()
+	ctx := t.Context()
 	cohort := utiltesting.MakeCohort("cohort").ResourceGroup(
 		utiltesting.MakeFlavorQuotas("red").Resource("cpu", "10").FlavorQuotas,
 	).Obj()
diff --git a/pkg/controller/jobframework/base_webhook_test.go b/pkg/controller/jobframework/base_webhook_test.go
index 11a06ede7..d9f72e76c 100644
--- a/pkg/controller/jobframework/base_webhook_test.go
+++ b/pkg/controller/jobframework/base_webhook_test.go
@@ -17,7 +17,6 @@ limitations under the License.
 package jobframework_test
 
 import (
-	"context"
 	"testing"
 
 	"github.com/google/go-cmp/cmp"
@@ -289,7 +288,7 @@ func TestBaseWebhookDefault(t *testing.T) {
 				Queues:                     queueManager,
 				Cache:                      cqCache,
 			}
-			if err := w.Default(context.Background(), tc.job); err != nil {
+			if err := w.Default(t.Context(), tc.job); err != nil {
 				t.Errorf("set defaults by base webhook")
 			}
 			if diff := cmp.Diff(tc.want, tc.job); len(diff) != 0 {
@@ -350,7 +349,7 @@ func TestValidateOnCreate(t *testing.T) {
 			w := &jobframework.BaseWebhook{
 				FromObject: makeTestGenericJob().withValidateOnCreate(tc.validateOnCreate).fromObject,
 			}
-			gotWarn, gotErr := w.ValidateCreate(context.Background(), tc.job)
+			gotWarn, gotErr := w.ValidateCreate(t.Context(), tc.job)
 			if diff := cmp.Diff(tc.wantErr, gotErr); diff != "" {
 				t.Errorf("validate create err mismatch (-want +got):\n%s", diff)
 			}
@@ -427,7 +426,7 @@ func TestValidateOnUpdate(t *testing.T) {
 			w := &jobframework.BaseWebhook{
 				FromObject: makeTestGenericJob().withValidateOnUpdate(tc.validateOnUpdate).fromObject,
 			}
-			gotWarn, gotErr := w.ValidateUpdate(context.Background(), tc.oldJob, tc.job)
+			gotWarn, gotErr := w.ValidateUpdate(t.Context(), tc.oldJob, tc.job)
 			if diff := cmp.Diff(tc.wantErr, gotErr); diff != "" {
 				t.Errorf("validate create err mismatch (-want +got):\n%s", diff)
 			}
diff --git a/pkg/controller/jobframework/setup_test.go b/pkg/controller/jobframework/setup_test.go
index 9ae85bca1..07aeb9dce 100644
--- a/pkg/controller/jobframework/setup_test.go
+++ b/pkg/controller/jobframework/setup_test.go
@@ -259,7 +259,7 @@ func TestSetupIndexes(t *testing.T) {
 	}
 	for name, tc := range cases {
 		t.Run(name, func(t *testing.T) {
-			ctx, cancel := context.WithCancel(context.Background())
+			ctx, cancel := context.WithCancel(t.Context())
 			defer cancel()
 
 			builder := utiltesting.NewClientBuilder().WithObjects(utiltesting.MakeNamespace(testNamespace))
diff --git a/pkg/controller/jobframework/webhook/defaulter_test.go b/pkg/controller/jobframework/webhook/defaulter_test.go
index 1f2c085aa..06db51f37 100644
--- a/pkg/controller/jobframework/webhook/defaulter_test.go
+++ b/pkg/controller/jobframework/webhook/defaulter_test.go
@@ -82,7 +82,7 @@ func TestLossLessDefaulter(t *testing.T) {
 			},
 		},
 	}
-	resp := handler.Handle(context.Background(), req)
+	resp := handler.Handle(t.Context(), req)
 	if !resp.Allowed {
 		t.Errorf("Response not allowed")
 	}
diff --git a/pkg/controller/jobs/jobset/jobset_webhook_test.go b/pkg/controller/jobs/jobset/jobset_webhook_test.go
index 1d2c2fbee..f79821126 100644
--- a/pkg/controller/jobs/jobset/jobset_webhook_test.go
+++ b/pkg/controller/jobs/jobset/jobset_webhook_test.go
@@ -17,7 +17,6 @@ limitations under the License.
 package jobset
 
 import (
-	"context"
 	"testing"
 
 	"github.com/google/go-cmp/cmp"
@@ -105,7 +104,7 @@ func TestValidateCreate(t *testing.T) {
 	for _, tc := range testcases {
 		t.Run(tc.name, func(t *testing.T) {
 			jsw := &JobSetWebhook{}
-			_, gotErr := jsw.ValidateCreate(context.Background(), tc.job)
+			_, gotErr := jsw.ValidateCreate(t.Context(), tc.job)
 
 			if diff := cmp.Diff(tc.wantErr, gotErr); diff != "" {
 				t.Errorf("validateCreate() mismatch (-want +got):\n%s", diff)
diff --git a/pkg/controller/jobs/leaderworkerset/leaderworkerset_pod_reconciler_test.go b/pkg/controller/jobs/leaderworkerset/leaderworkerset_pod_reconciler_test.go
index 510658f3e..8f95a6409 100644
--- a/pkg/controller/jobs/leaderworkerset/leaderworkerset_pod_reconciler_test.go
+++ b/pkg/controller/jobs/leaderworkerset/leaderworkerset_pod_reconciler_test.go
@@ -28,7 +28,6 @@ import (
 	leaderworkersetv1 "sigs.k8s.io/lws/api/leaderworkerset/v1"
 
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta1"
-	"sigs.k8s.io/kueue/pkg/controller/constants"
 	podconstants "sigs.k8s.io/kueue/pkg/controller/jobs/pod/constants"
 	utiltesting "sigs.k8s.io/kueue/pkg/util/testing"
 	"sigs.k8s.io/kueue/pkg/util/testingjobs/leaderworkerset"
@@ -118,31 +117,6 @@ func TestPodReconciler(t *testing.T) {
 				Annotation(podconstants.RoleHashAnnotation, string(kueue.DefaultPodSetName)).
 				Obj(),
 		},
-		"should set default values and priority class when has value": {
-			lws: leaderworkerset.MakeLeaderWorkerSet("lws", "ns").
-				UID(testUID).
-				Queue("queue").
-				Label(constants.WorkloadPriorityClassLabel, "test").
-				Obj(),
-			pod: testingjobspod.MakePod("pod", "ns").
-				Label(leaderworkersetv1.SetNameLabelKey, "lws").
-				Label(leaderworkersetv1.GroupIndexLabelKey, "0").
-				Annotation(podconstants.SuspendedByParentAnnotation, FrameworkName).
-				Annotation(podconstants.GroupServingAnnotationKey, podconstants.GroupServingAnnotationValue).
-				Obj(),
-			wantPod: testingjobspod.MakePod("pod", "ns").
-				Label(leaderworkersetv1.SetNameLabelKey, "lws").
-				Label(leaderworkersetv1.GroupIndexLabelKey, "0").
-				Label(constants.WorkloadPriorityClassLabel, "test").
-				Queue("queue").
-				Group(GetWorkloadName(types.UID(testUID), "lws", "0")).
-				GroupTotalCount("1").
-				PrebuiltWorkload(GetWorkloadName(types.UID(testUID), "lws", "0")).
-				Annotation(podconstants.SuspendedByParentAnnotation, FrameworkName).
-				Annotation(podconstants.GroupServingAnnotationKey, podconstants.GroupServingAnnotationValue).
-				Annotation(podconstants.RoleHashAnnotation, string(kueue.DefaultPodSetName)).
-				Obj(),
-		},
 	}
 	for name, tc := range cases {
 		t.Run(name, func(t *testing.T) {
diff --git a/pkg/controller/jobs/leaderworkerset/leaderworkerset_reconciler_test.go b/pkg/controller/jobs/leaderworkerset/leaderworkerset_reconciler_test.go
index f1a99b694..ef9b7ecd1 100644
--- a/pkg/controller/jobs/leaderworkerset/leaderworkerset_reconciler_test.go
+++ b/pkg/controller/jobs/leaderworkerset/leaderworkerset_reconciler_test.go
@@ -33,6 +33,7 @@ import (
 
 	kueuealpha "sigs.k8s.io/kueue/apis/kueue/v1alpha1"
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta1"
+	"sigs.k8s.io/kueue/pkg/constants"
 	"sigs.k8s.io/kueue/pkg/controller/jobframework"
 	podconstants "sigs.k8s.io/kueue/pkg/controller/jobs/pod/constants"
 	utiltesting "sigs.k8s.io/kueue/pkg/util/testing"
@@ -54,13 +55,14 @@ var (
 
 func TestReconciler(t *testing.T) {
 	cases := map[string]struct {
-		labelKeysToCopy     []string
-		leaderWorkerSet     *leaderworkersetv1.LeaderWorkerSet
-		workloads           []kueue.Workload
-		wantLeaderWorkerSet *leaderworkersetv1.LeaderWorkerSet
-		wantWorkloads       []kueue.Workload
-		wantEvents          []utiltesting.EventRecord
-		wantErr             error
+		labelKeysToCopy         []string
+		leaderWorkerSet         *leaderworkersetv1.LeaderWorkerSet
+		workloads               []kueue.Workload
+		workloadPriorityClasses []kueue.WorkloadPriorityClass
+		wantLeaderWorkerSet     *leaderworkersetv1.LeaderWorkerSet
+		wantWorkloads           []kueue.Workload
+		wantEvents              []utiltesting.EventRecord
+		wantErr                 error
 	}{
 		"should create prebuilt workload": {
 			leaderWorkerSet:     leaderworkerset.MakeLeaderWorkerSet(testLWS, testNS).UID(testUID).Obj(),
@@ -82,6 +84,7 @@ func TestReconciler(t *testing.T) {
 							Count:           1,
 							TopologyRequest: nil,
 						}).
+					Priority(0).
 					Obj(),
 			},
 			wantEvents: []utiltesting.EventRecord{
@@ -150,6 +153,7 @@ func TestReconciler(t *testing.T) {
 							TopologyRequest: nil,
 						},
 					).
+					Priority(0).
 					Obj(),
 			},
 			wantEvents: []utiltesting.EventRecord{
@@ -220,6 +224,7 @@ func TestReconciler(t *testing.T) {
 							TopologyRequest: nil,
 						},
 					).
+					Priority(0).
 					Obj(),
 				*utiltesting.MakeWorkload(GetWorkloadName(types.UID(testUID), testLWS, "1"), testNS).
 					Annotation(podconstants.IsGroupWorkloadAnnotationKey, podconstants.IsGroupWorkloadAnnotationValue).
@@ -250,6 +255,7 @@ func TestReconciler(t *testing.T) {
 							TopologyRequest: nil,
 						},
 					).
+					Priority(0).
 					Obj(),
 			},
 			wantEvents: []utiltesting.EventRecord{
@@ -367,6 +373,54 @@ func TestReconciler(t *testing.T) {
 							},
 						},
 					).
+					Priority(0).
+					Obj(),
+			},
+			wantEvents: []utiltesting.EventRecord{
+				{
+					Key:       types.NamespacedName{Name: testLWS, Namespace: testNS},
+					EventType: corev1.EventTypeNormal,
+					Reason:    jobframework.ReasonCreatedWorkload,
+					Message: fmt.Sprintf(
+						"Created Workload: %s/%s",
+						testNS,
+						GetWorkloadName(types.UID(testUID), testLWS, "0"),
+					),
+				},
+			},
+		},
+		"should create prebuilt workload with workload priority": {
+			leaderWorkerSet: leaderworkerset.MakeLeaderWorkerSet(testLWS, testNS).
+				WorkloadPriorityClass("high-priority").
+				UID(testUID).
+				Obj(),
+			workloadPriorityClasses: []kueue.WorkloadPriorityClass{
+				*utiltesting.MakeWorkloadPriorityClass("high-priority").PriorityValue(5000).Obj(),
+			},
+			wantLeaderWorkerSet: leaderworkerset.MakeLeaderWorkerSet(testLWS, testNS).
+				WorkloadPriorityClass("high-priority").
+				UID(testUID).
+				Obj(),
+			wantWorkloads: []kueue.Workload{
+				*utiltesting.MakeWorkload(GetWorkloadName(types.UID(testUID), testLWS, "0"), testNS).
+					Annotation(podconstants.IsGroupWorkloadAnnotationKey, podconstants.IsGroupWorkloadAnnotationValue).
+					Finalizers(kueue.ResourceInUseFinalizerName).
+					PodSets(
+						kueue.PodSet{
+							Name: kueue.DefaultPodSetName,
+							Template: corev1.PodTemplateSpec{
+								Spec: corev1.PodSpec{
+									Containers: []corev1.Container{
+										{Name: "c", Image: "pause"},
+									},
+								},
+							},
+							Count:           1,
+							TopologyRequest: nil,
+						}).
+					PriorityClass("high-priority").
+					Priority(5000).
+					PriorityClassSource(constants.WorkloadPriorityClassSource).
 					Obj(),
 			},
 			wantEvents: []utiltesting.EventRecord{
@@ -388,11 +442,14 @@ func TestReconciler(t *testing.T) {
 			ctx, _ := utiltesting.ContextWithLog(t)
 			clientBuilder := utiltesting.NewClientBuilder(leaderworkersetv1.AddToScheme)
 
-			objs := make([]client.Object, 0, len(tc.workloads)+1)
+			objs := make([]client.Object, 0, len(tc.workloads)+len(tc.workloadPriorityClasses)+1)
 			objs = append(objs, tc.leaderWorkerSet)
 			for _, wl := range tc.workloads {
 				objs = append(objs, &wl)
 			}
+			for _, wpc := range tc.workloadPriorityClasses {
+				objs = append(objs, &wpc)
+			}
 
 			kClient := clientBuilder.WithObjects(objs...).Build()
 			recorder := &utiltesting.EventRecorder{}
diff --git a/pkg/controller/jobs/leaderworkerset/leaderworkerset_webhook_test.go b/pkg/controller/jobs/leaderworkerset/leaderworkerset_webhook_test.go
index f44080766..42bc3ebbc 100644
--- a/pkg/controller/jobs/leaderworkerset/leaderworkerset_webhook_test.go
+++ b/pkg/controller/jobs/leaderworkerset/leaderworkerset_webhook_test.go
@@ -17,7 +17,6 @@ limitations under the License.
 package leaderworkerset
 
 import (
-	"context"
 	"testing"
 
 	"github.com/google/go-cmp/cmp"
@@ -49,6 +48,25 @@ func TestDefault(t *testing.T) {
 		enableIntegrations         []string
 		want                       *leaderworkersetv1.LeaderWorkerSet
 	}{
+		"LeaderWorkerSet with WorkloadPriorityClass": {
+			localQueueDefaulting: true,
+			defaultLqExist:       true,
+			lws: testingleaderworkerset.MakeLeaderWorkerSet("test-lws", "default").
+				LeaderTemplate(corev1.PodTemplateSpec{}).
+				WorkloadPriorityClass("high-priority").
+				Obj(),
+			want: testingleaderworkerset.MakeLeaderWorkerSet("test-lws", "default").
+				LeaderTemplate(corev1.PodTemplateSpec{}).
+				Queue("default").
+				WorkloadPriorityClass("high-priority").
+				LeaderTemplateSpecLabel(constants.WorkloadPriorityClassLabel, "high-priority").
+				LeaderTemplateSpecAnnotation(podconstants.SuspendedByParentAnnotation, FrameworkName).
+				LeaderTemplateSpecAnnotation(podconstants.GroupServingAnnotationKey, podconstants.GroupServingAnnotationValue).
+				WorkerTemplateSpecLabel(constants.WorkloadPriorityClassLabel, "high-priority").
+				WorkerTemplateSpecAnnotation(podconstants.SuspendedByParentAnnotation, FrameworkName).
+				WorkerTemplateSpecAnnotation(podconstants.GroupServingAnnotationKey, podconstants.GroupServingAnnotationValue).
+				Obj(),
+		},
 		"LocalQueueDefaulting enabled, default lq is created, job doesn't have queue label": {
 			localQueueDefaulting: true,
 			defaultLqExist:       true,
@@ -641,7 +659,7 @@ func TestValidateUpdate(t *testing.T) {
 				jobframework.EnableIntegrationsForTest(t, integration)
 			}
 
-			ctx := context.Background()
+			ctx := t.Context()
 
 			wh := &Webhook{}
 
diff --git a/pkg/controller/jobs/mpijob/mpijob_webhook_test.go b/pkg/controller/jobs/mpijob/mpijob_webhook_test.go
index ce8afbdfd..5a817f9d7 100644
--- a/pkg/controller/jobs/mpijob/mpijob_webhook_test.go
+++ b/pkg/controller/jobs/mpijob/mpijob_webhook_test.go
@@ -17,7 +17,6 @@ limitations under the License.
 package mpijob
 
 import (
-	"context"
 	"testing"
 
 	"github.com/google/go-cmp/cmp"
@@ -123,7 +122,7 @@ func TestValidateCreate(t *testing.T) {
 	for _, tc := range testcases {
 		t.Run(tc.name, func(t *testing.T) {
 			jsw := &MpiJobWebhook{}
-			_, gotErr := jsw.ValidateCreate(context.Background(), tc.job)
+			_, gotErr := jsw.ValidateCreate(t.Context(), tc.job)
 
 			if diff := cmp.Diff(tc.wantErr, gotErr); diff != "" {
 				t.Errorf("validateCreate() mismatch (-want +got):\n%s", diff)
diff --git a/pkg/controller/jobs/raycluster/raycluster_webhook_test.go b/pkg/controller/jobs/raycluster/raycluster_webhook_test.go
index c6f4eda22..3303ac8b9 100644
--- a/pkg/controller/jobs/raycluster/raycluster_webhook_test.go
+++ b/pkg/controller/jobs/raycluster/raycluster_webhook_test.go
@@ -17,7 +17,6 @@ limitations under the License.
 package raycluster
 
 import (
-	"context"
 	"fmt"
 	"testing"
 
@@ -125,7 +124,7 @@ func TestValidateDefault(t *testing.T) {
 				cache:                      cqCache,
 			}
 			result := tc.oldJob.DeepCopy()
-			if err := wh.Default(context.Background(), result); err != nil {
+			if err := wh.Default(t.Context(), result); err != nil {
 				t.Errorf("unexpected Default() error: %s", err)
 			}
 			if diff := cmp.Diff(tc.newJob, result); diff != "" {
@@ -257,7 +256,7 @@ func TestValidateCreate(t *testing.T) {
 			wh := &RayClusterWebhook{
 				manageJobsWithoutQueueName: tc.manageAll,
 			}
-			_, result := wh.ValidateCreate(context.Background(), tc.job)
+			_, result := wh.ValidateCreate(t.Context(), tc.job)
 			if diff := cmp.Diff(tc.wantErr, result); diff != "" {
 				t.Errorf("ValidateCreate() mismatch (-want +got):\n%s", diff)
 			}
@@ -323,7 +322,7 @@ func TestValidateUpdate(t *testing.T) {
 			wh := &RayClusterWebhook{
 				manageJobsWithoutQueueName: tc.manageAll,
 			}
-			_, result := wh.ValidateUpdate(context.Background(), tc.oldJob, tc.newJob)
+			_, result := wh.ValidateUpdate(t.Context(), tc.oldJob, tc.newJob)
 			if diff := cmp.Diff(tc.wantErr, result); diff != "" {
 				t.Errorf("ValidateUpdate() mismatch (-want +got):\n%s", diff)
 			}
diff --git a/pkg/controller/jobs/rayjob/rayjob_webhook_test.go b/pkg/controller/jobs/rayjob/rayjob_webhook_test.go
index d95588642..879fd1b61 100644
--- a/pkg/controller/jobs/rayjob/rayjob_webhook_test.go
+++ b/pkg/controller/jobs/rayjob/rayjob_webhook_test.go
@@ -17,7 +17,6 @@ limitations under the License.
 package rayjob
 
 import (
-	"context"
 	"fmt"
 	"testing"
 
@@ -124,7 +123,7 @@ func TestValidateDefault(t *testing.T) {
 				cache:                      cqCache,
 			}
 			result := tc.oldJob.DeepCopy()
-			if err := wh.Default(context.Background(), result); err != nil {
+			if err := wh.Default(t.Context(), result); err != nil {
 				t.Errorf("unexpected Default() error: %s", err)
 			}
 			if diff := cmp.Diff(tc.newJob, result); diff != "" {
@@ -284,7 +283,7 @@ func TestValidateCreate(t *testing.T) {
 			wh := &RayJobWebhook{
 				manageJobsWithoutQueueName: tc.manageAll,
 			}
-			_, result := wh.ValidateCreate(context.Background(), tc.job)
+			_, result := wh.ValidateCreate(t.Context(), tc.job)
 			if diff := cmp.Diff(tc.wantErr, result); diff != "" {
 				t.Errorf("ValidateCreate() mismatch (-want +got):\n%s", diff)
 			}
@@ -381,7 +380,7 @@ func TestValidateUpdate(t *testing.T) {
 			wh := &RayJobWebhook{
 				manageJobsWithoutQueueName: tc.manageAll,
 			}
-			_, result := wh.ValidateUpdate(context.Background(), tc.oldJob, tc.newJob)
+			_, result := wh.ValidateUpdate(t.Context(), tc.oldJob, tc.newJob)
 			if diff := cmp.Diff(tc.wantErr, result); diff != "" {
 				t.Errorf("ValidateUpdate() mismatch (-want +got):\n%s", diff)
 			}
diff --git a/pkg/controller/jobs/statefulset/statefulset_webhook_test.go b/pkg/controller/jobs/statefulset/statefulset_webhook_test.go
index 1e61fe688..55930510b 100644
--- a/pkg/controller/jobs/statefulset/statefulset_webhook_test.go
+++ b/pkg/controller/jobs/statefulset/statefulset_webhook_test.go
@@ -17,7 +17,6 @@ limitations under the License.
 package statefulset
 
 import (
-	"context"
 	"testing"
 
 	"github.com/google/go-cmp/cmp"
@@ -611,7 +610,7 @@ func TestValidateUpdate(t *testing.T) {
 	for name, tc := range testCases {
 		t.Run(name, func(t *testing.T) {
 			t.Cleanup(jobframework.EnableIntegrationsForTest(t, tc.integrations...))
-			ctx := context.Background()
+			ctx := t.Context()
 
 			wh := &Webhook{}
 
diff --git a/pkg/queue/cluster_queue_test.go b/pkg/queue/cluster_queue_test.go
index af0702264..23e6f268b 100644
--- a/pkg/queue/cluster_queue_test.go
+++ b/pkg/queue/cluster_queue_test.go
@@ -17,7 +17,6 @@ limitations under the License.
 package queue
 
 import (
-	"context"
 	"testing"
 	"time"
 
@@ -443,7 +442,7 @@ func TestClusterQueueImpl(t *testing.T) {
 
 			if test.queueInadmissibleWorkloads {
 				if diff := cmp.Diff(test.wantInadmissibleWorkloadsRequeued,
-					cq.QueueInadmissibleWorkloads(context.Background(), cl)); diff != "" {
+					cq.QueueInadmissibleWorkloads(t.Context(), cl)); diff != "" {
 					t.Errorf("Unexpected requeuing of inadmissible workloads (-want,+got):\n%s", diff)
 				}
 			}
@@ -464,7 +463,7 @@ func TestQueueInadmissibleWorkloadsDuringScheduling(t *testing.T) {
 	cq.namespaceSelector = labels.Everything()
 	wl := utiltesting.MakeWorkload("workload-1", defaultNamespace).Obj()
 	cl := utiltesting.NewFakeClient(wl, utiltesting.MakeNamespace(defaultNamespace))
-	ctx := context.Background()
+	ctx := t.Context()
 	cq.PushOrUpdate(workload.NewInfo(wl))
 
 	wantActiveWorkloads := []string{workload.Key(wl)}
diff --git a/pkg/queue/manager_test.go b/pkg/queue/manager_test.go
index 5bc256c56..8a7ed1cb2 100644
--- a/pkg/queue/manager_test.go
+++ b/pkg/queue/manager_test.go
@@ -57,7 +57,7 @@ func TestAddLocalQueueOrphans(t *testing.T) {
 	)
 	manager := NewManager(kClient, nil)
 	q := utiltesting.MakeLocalQueue("foo", "earth").Obj()
-	if err := manager.AddLocalQueue(context.Background(), q); err != nil {
+	if err := manager.AddLocalQueue(t.Context(), q); err != nil {
 		t.Fatalf("Failed adding queue: %v", err)
 	}
 	qImpl := manager.localQueues[Key(q)]
@@ -88,7 +88,7 @@ func TestAddClusterQueueOrphans(t *testing.T) {
 		queues[0],
 		queues[1],
 	)
-	ctx := context.Background()
+	ctx := t.Context()
 	manager := NewManager(kClient, nil)
 	cq := utiltesting.MakeClusterQueue("cq").Obj()
 	if err := manager.AddClusterQueue(ctx, cq); err != nil {
@@ -141,7 +141,7 @@ func TestUpdateClusterQueue(t *testing.T) {
 		utiltesting.MakeWorkload("b", defaultNamespace).Queue("bar").Creation(now).Obj(),
 	}
 	// Setup.
-	ctx := context.Background()
+	ctx := t.Context()
 	cl := utiltesting.NewFakeClient(utiltesting.MakeNamespace(defaultNamespace))
 	manager := NewManager(cl, nil)
 	for _, cq := range clusterQueues {
@@ -223,7 +223,7 @@ func TestRequeueWorkloadsCohortCycle(t *testing.T) {
 	lq := utiltesting.MakeLocalQueue("foo", defaultNamespace).ClusterQueue("cq1").Obj()
 	wl := utiltesting.MakeWorkload("a", defaultNamespace).Queue("foo").Creation(time.Now()).Obj()
 	// Setup.
-	ctx := context.Background()
+	ctx := t.Context()
 	cl := utiltesting.NewFakeClient(utiltesting.MakeNamespace(defaultNamespace))
 	manager := NewManager(cl, nil)
 	for _, cohort := range cohorts {
@@ -254,7 +254,7 @@ func TestRequeueWorkloadsCohortCycle(t *testing.T) {
 func TestClusterQueueToActive(t *testing.T) {
 	stoppedCq := utiltesting.MakeClusterQueue("cq1").Cohort("alpha").Condition(kueue.ClusterQueueActive, metav1.ConditionFalse, "ByTest", "by test").Obj()
 	runningCq := utiltesting.MakeClusterQueue("cq1").Cohort("alpha").Condition(kueue.ClusterQueueActive, metav1.ConditionTrue, "ByTest", "by test").Obj()
-	ctx := context.Background()
+	ctx := t.Context()
 	cl := utiltesting.NewFakeClient(utiltesting.MakeNamespace(defaultNamespace))
 	manager := NewManager(cl, nil)
 
@@ -326,7 +326,7 @@ func TestUpdateLocalQueue(t *testing.T) {
 	if err := kueue.AddToScheme(scheme); err != nil {
 		t.Fatalf("Failed adding kueue scheme: %s", err)
 	}
-	ctx := context.Background()
+	ctx := t.Context()
 	manager := NewManager(utiltesting.NewFakeClient(), nil)
 	for _, cq := range clusterQueues {
 		if err := manager.AddClusterQueue(ctx, cq); err != nil {
@@ -371,7 +371,7 @@ func TestDeleteLocalQueue(t *testing.T) {
 	q := utiltesting.MakeLocalQueue("foo", "").ClusterQueue("cq").Obj()
 	wl := utiltesting.MakeWorkload("a", "").Queue("foo").Obj()
 
-	ctx := context.Background()
+	ctx := t.Context()
 	cl := utiltesting.NewFakeClient(wl)
 	manager := NewManager(cl, nil)
 
@@ -399,7 +399,7 @@ func TestDeleteLocalQueue(t *testing.T) {
 func TestAddWorkload(t *testing.T) {
 	manager := NewManager(utiltesting.NewFakeClient(), nil)
 	cq := utiltesting.MakeClusterQueue("cq").Obj()
-	if err := manager.AddClusterQueue(context.Background(), cq); err != nil {
+	if err := manager.AddClusterQueue(t.Context(), cq); err != nil {
 		t.Fatalf("Failed adding clusterQueue %s: %v", cq.Name, err)
 	}
 	queues := []*kueue.LocalQueue{
@@ -407,7 +407,7 @@ func TestAddWorkload(t *testing.T) {
 		utiltesting.MakeLocalQueue("bar", "mars").Obj(),
 	}
 	for _, q := range queues {
-		if err := manager.AddLocalQueue(context.Background(), q); err != nil {
+		if err := manager.AddLocalQueue(t.Context(), q); err != nil {
 			t.Fatalf("Failed adding queue %s: %v", q.Name, err)
 		}
 	}
@@ -466,7 +466,7 @@ func TestAddWorkload(t *testing.T) {
 }
 
 func TestStatus(t *testing.T) {
-	ctx := context.Background()
+	ctx := t.Context()
 	scheme := runtime.NewScheme()
 	if err := kueue.AddToScheme(scheme); err != nil {
 		t.Fatalf("Failed adding kueue scheme: %s", err)
@@ -632,7 +632,7 @@ func TestRequeueWorkloadStrictFIFO(t *testing.T) {
 		t.Run(tc.workload.Name, func(t *testing.T) {
 			cl := utiltesting.NewFakeClient()
 			manager := NewManager(cl, nil)
-			ctx := context.Background()
+			ctx := t.Context()
 			if err := manager.AddClusterQueue(ctx, cq); err != nil {
 				t.Fatalf("Failed adding cluster queue %s: %v", cq.Name, err)
 			}
@@ -791,7 +791,7 @@ func TestUpdateWorkload(t *testing.T) {
 	for name, tc := range cases {
 		t.Run(name, func(t *testing.T) {
 			manager := NewManager(utiltesting.NewFakeClient(), nil)
-			ctx := context.Background()
+			ctx := t.Context()
 			for _, cq := range tc.clusterQueues {
 				if err := manager.AddClusterQueue(ctx, cq); err != nil {
 					t.Fatalf("Adding cluster queue %s: %v", cq.Name, err)
@@ -904,7 +904,7 @@ func TestHeads(t *testing.T) {
 	}
 	for _, tc := range tests {
 		t.Run(tc.name, func(t *testing.T) {
-			ctx, cancel := context.WithTimeout(context.Background(), headsTimeout)
+			ctx, cancel := context.WithTimeout(t.Context(), headsTimeout)
 			defer cancel()
 			fakeC := &fakeStatusChecker{}
 			manager := NewManager(utiltesting.NewFakeClient(), fakeC)
@@ -1145,7 +1145,7 @@ func TestHeadsAsync(t *testing.T) {
 	}
 	for name, tc := range cases {
 		t.Run(name, func(t *testing.T) {
-			ctx, cancel := context.WithTimeout(context.Background(), headsTimeout)
+			ctx, cancel := context.WithTimeout(t.Context(), headsTimeout)
 			defer cancel()
 			client := utiltesting.NewFakeClient(tc.initialObjs...)
 			manager := NewManager(client, nil)
@@ -1162,7 +1162,7 @@ func TestHeadsAsync(t *testing.T) {
 // TestHeadsCancelled ensures that the Heads call returns when the context is closed.
 func TestHeadsCancelled(t *testing.T) {
 	manager := NewManager(utiltesting.NewFakeClient(), nil)
-	ctx, cancel := context.WithCancel(context.Background())
+	ctx, cancel := context.WithCancel(t.Context())
 	go func() {
 		cancel()
 	}()
@@ -1217,7 +1217,7 @@ func TestGetPendingWorkloadsInfo(t *testing.T) {
 	if err := kueue.AddToScheme(scheme); err != nil {
 		t.Fatalf("Failed adding kueue scheme: %s", err)
 	}
-	ctx := context.Background()
+	ctx := t.Context()
 	manager := NewManager(utiltesting.NewFakeClient(), nil)
 	for _, cq := range clusterQueues {
 		if err := manager.AddClusterQueue(ctx, cq); err != nil {
diff --git a/pkg/scheduler/scheduler_test.go b/pkg/scheduler/scheduler_test.go
index a8d78d8fb..a004b7e6e 100644
--- a/pkg/scheduler/scheduler_test.go
+++ b/pkg/scheduler/scheduler_test.go
@@ -3359,7 +3359,7 @@ func TestEntryOrdering(t *testing.T) {
 	} {
 		t.Run(tc.name, func(t *testing.T) {
 			features.SetFeatureGateDuringTest(t, features.PrioritySortingWithinCohort, tc.prioritySorting)
-			iter := makeIterator(context.Background(), tc.input, tc.workloadOrdering, false)
+			iter := makeIterator(t.Context(), tc.input, tc.workloadOrdering, false)
 			order := make([]string, len(tc.input))
 			for i := range tc.input {
 				order[i] = iter.pop().Obj.Name
diff --git a/pkg/util/admissioncheck/admissioncheck_test.go b/pkg/util/admissioncheck/admissioncheck_test.go
index b86ab5947..aa83128c2 100644
--- a/pkg/util/admissioncheck/admissioncheck_test.go
+++ b/pkg/util/admissioncheck/admissioncheck_test.go
@@ -104,7 +104,7 @@ func TestConfigHelper(t *testing.T) {
 				builder = builder.WithObjects(tc.config)
 			}
 			client := builder.Build()
-			ctx, cancel := context.WithCancel(context.Background())
+			ctx, cancel := context.WithCancel(t.Context())
 			defer cancel()
 
 			helper, err := NewConfigHelper[*kueue.ProvisioningRequestConfig](client)
@@ -208,7 +208,7 @@ func TestFilterCheckStates(t *testing.T) {
 				builder = builder.WithLists(&kueue.AdmissionCheckList{Items: tc.admissionchecks})
 			}
 			client := builder.Build()
-			ctx, cancel := context.WithCancel(context.Background())
+			ctx, cancel := context.WithCancel(t.Context())
 			defer cancel()
 
 			gotResult, _ := FilterForController(ctx, client, tc.states, "test-controller")
diff --git a/pkg/util/parallelize/parallelize_test.go b/pkg/util/parallelize/parallelize_test.go
index f21cf504e..4eb891053 100644
--- a/pkg/util/parallelize/parallelize_test.go
+++ b/pkg/util/parallelize/parallelize_test.go
@@ -17,7 +17,6 @@ limitations under the License.
 package parallelize
 
 import (
-	"context"
 	"errors"
 	"testing"
 
@@ -54,7 +53,7 @@ func TestUntil(t *testing.T) {
 	for name, tc := range cases {
 		t.Run(name, func(t *testing.T) {
 			result = make([]int, 5)
-			err := Until(context.Background(), len(result), tc.op)
+			err := Until(t.Context(), len(result), tc.op)
 			if !errors.Is(err, tc.wantErr) {
 				t.Errorf("Got error %q, want %q", err, tc.wantErr)
 			}
diff --git a/pkg/util/priority/priority_test.go b/pkg/util/priority/priority_test.go
index 060d27d5b..624f64861 100644
--- a/pkg/util/priority/priority_test.go
+++ b/pkg/util/priority/priority_test.go
@@ -17,7 +17,6 @@ limitations under the License.
 package priority
 
 import (
-	"context"
 	"testing"
 
 	"github.com/google/go-cmp/cmp"
@@ -141,7 +140,7 @@ func TestGetPriorityFromPriorityClass(t *testing.T) {
 			builder := fake.NewClientBuilder().WithScheme(scheme).WithLists(tt.priorityClassList)
 			client := builder.Build()
 
-			name, source, value, err := GetPriorityFromPriorityClass(context.Background(), client, tt.priorityClassName)
+			name, source, value, err := GetPriorityFromPriorityClass(t.Context(), client, tt.priorityClassName)
 			if diff := cmp.Diff(tt.wantErr, err); diff != "" {
 				t.Errorf("unexpected error (-want,+got):\n%s", diff)
 			}
@@ -205,7 +204,7 @@ func TestGetPriorityFromWorkloadPriorityClass(t *testing.T) {
 			builder := fake.NewClientBuilder().WithScheme(scheme).WithLists(tt.workloadPriorityClassList)
 			client := builder.Build()
 
-			name, source, value, err := GetPriorityFromWorkloadPriorityClass(context.Background(), client, tt.workloadPriorityClassName)
+			name, source, value, err := GetPriorityFromWorkloadPriorityClass(t.Context(), client, tt.workloadPriorityClassName)
 			if diff := cmp.Diff(tt.wantErr, err); diff != "" {
 				t.Errorf("unexpected error (-want,+got):\n%s", diff)
 			}
diff --git a/pkg/util/routine/error_channel_test.go b/pkg/util/routine/error_channel_test.go
index 6fac1aa11..c50c7564b 100644
--- a/pkg/util/routine/error_channel_test.go
+++ b/pkg/util/routine/error_channel_test.go
@@ -35,7 +35,7 @@ func TestErrorChannel(t *testing.T) {
 		t.Errorf("expect %v from err channel, but got %v", err, actualErr)
 	}
 
-	ctx, cancel := context.WithCancel(context.Background())
+	ctx, cancel := context.WithCancel(t.Context())
 	errCh.SendErrorWithCancel(err, cancel)
 	if actualErr := errCh.ReceiveError(); !errors.Is(actualErr, err) {
 		t.Errorf("expect %v from err channel, but got %v", err, actualErr)
diff --git a/pkg/util/testing/context.go b/pkg/util/testing/context.go
index d8c7d2c0f..8a8a12568 100644
--- a/pkg/util/testing/context.go
+++ b/pkg/util/testing/context.go
@@ -29,5 +29,5 @@ func ContextWithLog(t *testing.T) (context.Context, logr.Logger) {
 	logger := testr.NewWithOptions(t, testr.Options{
 		Verbosity: 2,
 	})
-	return ctrl.LoggerInto(context.Background(), logger), logger
+	return ctrl.LoggerInto(t.Context(), logger), logger
 }
diff --git a/pkg/util/testingjobs/leaderworkerset/wrappers.go b/pkg/util/testingjobs/leaderworkerset/wrappers.go
index 4d9efe332..cc0b620d2 100644
--- a/pkg/util/testingjobs/leaderworkerset/wrappers.go
+++ b/pkg/util/testingjobs/leaderworkerset/wrappers.go
@@ -130,6 +130,15 @@ func (w *LeaderWorkerSetWrapper) WorkerTemplateSpecQueue(q string) *LeaderWorker
 	return w.WorkerTemplateSpecLabel(constants.QueueLabel, q)
 }
 
+// LeaderTemplateSpecLabel sets the label of the pod template spec of the LeaderLeaderSet
+func (w *LeaderWorkerSetWrapper) LeaderTemplateSpecLabel(k, v string) *LeaderWorkerSetWrapper {
+	if w.Spec.LeaderWorkerTemplate.LeaderTemplate.Labels == nil {
+		w.Spec.LeaderWorkerTemplate.LeaderTemplate.Labels = make(map[string]string, 1)
+	}
+	w.Spec.LeaderWorkerTemplate.LeaderTemplate.Labels[k] = v
+	return w
+}
+
 // LeaderTemplateSpecAnnotation sets the annotation of the pod template spec of the LeaderLeaderSet
 func (w *LeaderWorkerSetWrapper) LeaderTemplateSpecAnnotation(k, v string) *LeaderWorkerSetWrapper {
 	if w.Spec.LeaderWorkerTemplate.LeaderTemplate.Annotations == nil {
@@ -210,3 +219,8 @@ func (w *LeaderWorkerSetWrapper) TerminationGracePeriod(seconds int64) *LeaderWo
 	w.Spec.LeaderWorkerTemplate.WorkerTemplate.Spec.TerminationGracePeriodSeconds = &seconds
 	return w
 }
+
+// WorkloadPriorityClass sets workloadpriorityclass.
+func (w *LeaderWorkerSetWrapper) WorkloadPriorityClass(wpc string) *LeaderWorkerSetWrapper {
+	return w.Label(constants.WorkloadPriorityClassLabel, wpc)
+}
diff --git a/pkg/util/testingjobs/statefulset/wrappers.go b/pkg/util/testingjobs/statefulset/wrappers.go
index 96861b03f..bb8b8dafa 100644
--- a/pkg/util/testingjobs/statefulset/wrappers.go
+++ b/pkg/util/testingjobs/statefulset/wrappers.go
@@ -221,3 +221,8 @@ func (ss *StatefulSetWrapper) TerminationGracePeriod(seconds int64) *StatefulSet
 	ss.Spec.Template.Spec.TerminationGracePeriodSeconds = &seconds
 	return ss
 }
+
+// WorkloadPriorityClass sets workloadpriorityclass.
+func (ss *StatefulSetWrapper) WorkloadPriorityClass(wpc string) *StatefulSetWrapper {
+	return ss.Label(constants.WorkloadPriorityClassLabel, wpc)
+}
diff --git a/pkg/util/wait/backoff_test.go b/pkg/util/wait/backoff_test.go
index 88a8a07cd..1be6fe99c 100644
--- a/pkg/util/wait/backoff_test.go
+++ b/pkg/util/wait/backoff_test.go
@@ -88,7 +88,7 @@ func TestUntilWithBackoff(t *testing.T) {
 	for _, testCase := range testCases {
 		t.Run(testCase.name, func(t *testing.T) {
 			timer := makeSpyTimer()
-			ctx, cancel := context.WithCancel(context.Background())
+			ctx, cancel := context.WithCancel(t.Context())
 			defer cancel()
 
 			i := 0
diff --git a/pkg/visibility/api/v1beta1/pending_workloads_cq_test.go b/pkg/visibility/api/v1beta1/pending_workloads_cq_test.go
index 12e62fbdc..b515e7767 100644
--- a/pkg/visibility/api/v1beta1/pending_workloads_cq_test.go
+++ b/pkg/visibility/api/v1beta1/pending_workloads_cq_test.go
@@ -322,7 +322,7 @@ func TestPendingWorkloadsInCQ(t *testing.T) {
 	for name, tc := range cases {
 		t.Run(name, func(t *testing.T) {
 			manager := queue.NewManager(utiltesting.NewFakeClient(), nil)
-			ctx, cancel := context.WithCancel(context.Background())
+			ctx, cancel := context.WithCancel(t.Context())
 			defer cancel()
 			go manager.CleanUpOnContext(ctx)
 			pendingWorkloadsInCqRest := NewPendingWorkloadsInCqREST(manager)
diff --git a/pkg/visibility/api/v1beta1/pending_workloads_lq_test.go b/pkg/visibility/api/v1beta1/pending_workloads_lq_test.go
index 5adf02dcd..fcd1e1fc0 100644
--- a/pkg/visibility/api/v1beta1/pending_workloads_lq_test.go
+++ b/pkg/visibility/api/v1beta1/pending_workloads_lq_test.go
@@ -439,7 +439,7 @@ func TestPendingWorkloadsInLQ(t *testing.T) {
 	for name, tc := range cases {
 		t.Run(name, func(t *testing.T) {
 			manager := queue.NewManager(utiltesting.NewFakeClient(), nil)
-			ctx, cancel := context.WithCancel(context.Background())
+			ctx, cancel := context.WithCancel(t.Context())
 			defer cancel()
 			go manager.CleanUpOnContext(ctx)
 			pendingWorkloadsInLqRest := NewPendingWorkloadsInLqREST(manager)
diff --git a/pkg/workload/workload_test.go b/pkg/workload/workload_test.go
index d3e1c226f..b9684d898 100644
--- a/pkg/workload/workload_test.go
+++ b/pkg/workload/workload_test.go
@@ -17,7 +17,6 @@ limitations under the License.
 package workload
 
 import (
-	"context"
 	"testing"
 	"time"
 
@@ -423,7 +422,7 @@ func TestUpdateWorkloadStatus(t *testing.T) {
 			workload := utiltesting.MakeWorkload("foo", "bar").Generation(1).Obj()
 			workload.Status = tc.oldStatus
 			cl := utiltesting.NewFakeClientSSAAsSM(workload)
-			ctx := context.Background()
+			ctx := t.Context()
 			err := UpdateStatus(ctx, cl, workload, tc.condType, tc.condStatus, tc.reason, tc.message, "manager-prefix", fakeClock)
 			if err != nil {
 				t.Fatalf("Failed updating status: %v", err)
diff --git a/test/e2e/certmanager/suite_test.go b/test/e2e/certmanager/suite_test.go
index 4941e4411..87b023ccc 100644
--- a/test/e2e/certmanager/suite_test.go
+++ b/test/e2e/certmanager/suite_test.go
@@ -25,7 +25,6 @@ import (
 
 	"github.com/onsi/ginkgo/v2"
 	"github.com/onsi/gomega"
-	ctrl "sigs.k8s.io/controller-runtime"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
 	"sigs.k8s.io/kueue/apis/config/v1beta1"
@@ -50,10 +49,10 @@ func TestAPIs(t *testing.T) {
 }
 
 var _ = ginkgo.BeforeSuite(func() {
-	ctrl.SetLogger(util.NewTestingLogger(ginkgo.GinkgoWriter, -3))
+	util.SetupLogger()
 
 	k8sClient, _ = util.CreateClientUsingCluster("")
-	ctx = context.Background()
+	ctx = ginkgo.GinkgoT().Context()
 
 	waitForAvailableStart := time.Now()
 	util.WaitForKueueAvailability(ctx, k8sClient)
diff --git a/test/e2e/customconfigs/skipjobswithoutqueuename_test.go b/test/e2e/customconfigs/skipjobswithoutqueuename_test.go
index 6a2a311de..5c832ac92 100644
--- a/test/e2e/customconfigs/skipjobswithoutqueuename_test.go
+++ b/test/e2e/customconfigs/skipjobswithoutqueuename_test.go
@@ -84,7 +84,10 @@ var _ = ginkgo.Describe("ManageJobsWithoutQueueName", ginkgo.Ordered, func() {
 			var testJob, createdJob *batchv1.Job
 			var jobLookupKey types.NamespacedName
 			ginkgo.By("creating an unsuspended job without a queue name", func() {
-				testJob = testingjob.MakeJob("test-job", ns.Name).Suspend(false).Obj()
+				testJob = testingjob.MakeJob("test-job", ns.Name).
+					Suspend(false).
+					Image(util.E2eTestAgnHostImage, util.BehaviorExitFast).
+					Obj()
 				gomega.Expect(k8sClient.Create(ctx, testJob)).Should(gomega.Succeed())
 			})
 
@@ -117,7 +120,7 @@ var _ = ginkgo.Describe("ManageJobsWithoutQueueName", ginkgo.Ordered, func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, wlLookupKey, createdWorkload)).Should(gomega.Succeed())
 					g.Expect(createdWorkload.Status.Admission).ShouldNot(gomega.BeNil())
-				}, util.Timeout, util.Interval).Should(gomega.Succeed())
+				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 			})
 		})
 
@@ -236,7 +239,9 @@ var _ = ginkgo.Describe("ManageJobsWithoutQueueName", ginkgo.Ordered, func() {
 			var testPod, createdPod *corev1.Pod
 			var podLookupKey types.NamespacedName
 			ginkgo.By("creating a pod without a queue name", func() {
-				testPod = testingpod.MakePod("test-pod", ns.Name).Obj()
+				testPod = testingpod.MakePod("test-pod", ns.Name).
+					Image(util.E2eTestAgnHostImage, util.BehaviorWaitForDeletion).
+					Obj()
 				gomega.Expect(k8sClient.Create(ctx, testPod)).Should(gomega.Succeed())
 			})
 
diff --git a/test/e2e/customconfigs/suite_test.go b/test/e2e/customconfigs/suite_test.go
index 5456f4765..1d84cb7a8 100644
--- a/test/e2e/customconfigs/suite_test.go
+++ b/test/e2e/customconfigs/suite_test.go
@@ -52,7 +52,7 @@ var _ = ginkgo.BeforeSuite(func() {
 	util.SetupLogger()
 
 	k8sClient, _ = util.CreateClientUsingCluster("")
-	ctx = context.Background()
+	ctx = ginkgo.GinkgoT().Context()
 
 	waitForAvailableStart := time.Now()
 	util.WaitForKueueAvailability(ctx, k8sClient)
diff --git a/test/e2e/multikueue/suite_test.go b/test/e2e/multikueue/suite_test.go
index 5c1344562..91a0dbd1c 100644
--- a/test/e2e/multikueue/suite_test.go
+++ b/test/e2e/multikueue/suite_test.go
@@ -267,7 +267,7 @@ var _ = ginkgo.BeforeSuite(func() {
 	worker1RestClient = util.CreateRestClient(worker1Cfg)
 	worker2RestClient = util.CreateRestClient(worker2Cfg)
 
-	ctx = context.Background()
+	ctx = ginkgo.GinkgoT().Context()
 
 	worker1Kconfig, err := kubeconfigForMultiKueueSA(ctx, k8sWorker1Client, worker1Cfg, "kueue-system", "mksa", worker1ClusterName)
 	gomega.Expect(err).NotTo(gomega.HaveOccurred())
diff --git a/test/e2e/singlecluster/leaderworkerset_test.go b/test/e2e/singlecluster/leaderworkerset_test.go
index 2c28ac60b..3320568cf 100644
--- a/test/e2e/singlecluster/leaderworkerset_test.go
+++ b/test/e2e/singlecluster/leaderworkerset_test.go
@@ -28,6 +28,7 @@ import (
 	leaderworkersetv1 "sigs.k8s.io/lws/api/leaderworkerset/v1"
 
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta1"
+	"sigs.k8s.io/kueue/pkg/constants"
 	"sigs.k8s.io/kueue/pkg/controller/jobs/leaderworkerset"
 	"sigs.k8s.io/kueue/pkg/util/testing"
 	leaderworkersettesting "sigs.k8s.io/kueue/pkg/util/testingjobs/leaderworkerset"
@@ -660,4 +661,134 @@ var _ = ginkgo.Describe("LeaderWorkerSet integration", func() {
 			})
 		})
 	})
+
+	ginkgo.When("LeaderWorkerSet created with WorkloadPriorityClass", func() {
+		var (
+			highPriorityWPC *kueue.WorkloadPriorityClass
+			lowPriorityWPC  *kueue.WorkloadPriorityClass
+		)
+
+		ginkgo.BeforeEach(func() {
+			highPriorityWPC = testing.MakeWorkloadPriorityClass("high-priority").
+				PriorityValue(5000).
+				Obj()
+			gomega.Expect(k8sClient.Create(ctx, highPriorityWPC)).To(gomega.Succeed())
+
+			lowPriorityWPC = testing.MakeWorkloadPriorityClass("low-priority").
+				PriorityValue(1000).
+				Obj()
+			gomega.Expect(k8sClient.Create(ctx, lowPriorityWPC)).To(gomega.Succeed())
+		})
+
+		ginkgo.AfterEach(func() {
+			util.ExpectObjectToBeDeleted(ctx, k8sClient, highPriorityWPC, true)
+			util.ExpectObjectToBeDeleted(ctx, k8sClient, lowPriorityWPC, true)
+		})
+
+		ginkgo.It("should allow to update the PodTemplate in LeaderWorkerSet", func() {
+			lowPriorityLWS := leaderworkersettesting.MakeLeaderWorkerSet("low-priority", ns.Name).
+				Image(util.E2eTestAgnHostImage, util.BehaviorWaitForDeletion).
+				Size(3).
+				Replicas(1).
+				RequestAndLimit(corev1.ResourceCPU, "1").
+				TerminationGracePeriod(1).
+				Queue(lq.Name).
+				WorkloadPriorityClass(lowPriorityWPC.Name).
+				Obj()
+			ginkgo.By("Create a low priority LeaderWorkerSet", func() {
+				gomega.Expect(k8sClient.Create(ctx, lowPriorityLWS)).To(gomega.Succeed())
+			})
+
+			ginkgo.By("Waiting for replicas is ready in low priority LeaderWorkerSet", func() {
+				createdLowPriorityLWS := &leaderworkersetv1.LeaderWorkerSet{}
+				gomega.Eventually(func(g gomega.Gomega) {
+					g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(lowPriorityLWS), createdLowPriorityLWS)).To(gomega.Succeed())
+					g.Expect(createdLowPriorityLWS.Status.ReadyReplicas).To(gomega.Equal(int32(1)))
+					g.Expect(createdLowPriorityLWS.Status.Conditions).To(gomega.ContainElement(
+						gomega.BeComparableTo(metav1.Condition{
+							Type:   "Available",
+							Status: metav1.ConditionTrue,
+							Reason: "AllGroupsReady",
+						}, util.IgnoreConditionTimestampsAndObservedGeneration, util.IgnoreConditionMessage),
+					))
+				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
+			})
+
+			createdLowPriorityWl := &kueue.Workload{}
+			lowPriorityWlLookupKey := types.NamespacedName{
+				Name:      leaderworkerset.GetWorkloadName(lowPriorityLWS.UID, lowPriorityLWS.Name, "0"),
+				Namespace: ns.Name,
+			}
+			ginkgo.By("Check the low priority Workload is created and admitted", func() {
+				gomega.Eventually(func(g gomega.Gomega) {
+					g.Expect(k8sClient.Get(ctx, lowPriorityWlLookupKey, createdLowPriorityWl)).To(gomega.Succeed())
+					g.Expect(createdLowPriorityWl.Spec.PriorityClassSource).To(gomega.Equal(constants.WorkloadPriorityClassSource))
+					g.Expect(createdLowPriorityWl.Spec.PriorityClassName).To(gomega.Equal(lowPriorityWPC.Name))
+					g.Expect(createdLowPriorityWl.Status.Conditions).To(testing.HaveConditionStatusTrue(kueue.WorkloadAdmitted))
+				}, util.Timeout, util.Interval).Should(gomega.Succeed())
+			})
+
+			highPriorityLWS := leaderworkersettesting.MakeLeaderWorkerSet("high-priority", ns.Name).
+				Image(util.E2eTestAgnHostImage, util.BehaviorWaitForDeletion).
+				Size(3).
+				Replicas(1).
+				RequestAndLimit(corev1.ResourceCPU, "1").
+				TerminationGracePeriod(1).
+				Queue(lq.Name).
+				WorkloadPriorityClass(highPriorityWPC.Name).
+				Obj()
+			ginkgo.By("Create a high priority LeaderWorkerSet", func() {
+				gomega.Expect(k8sClient.Create(ctx, highPriorityLWS)).To(gomega.Succeed())
+			})
+
+			ginkgo.By("Waiting for ready replicas in the high priority LeaderWorkerSet", func() {
+				createdHighPriorityLWS := &leaderworkersetv1.LeaderWorkerSet{}
+				gomega.Eventually(func(g gomega.Gomega) {
+					g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(highPriorityLWS), createdHighPriorityLWS)).To(gomega.Succeed())
+					g.Expect(createdHighPriorityLWS.Status.ReadyReplicas).To(gomega.Equal(int32(1)))
+					g.Expect(createdHighPriorityLWS.Status.Conditions).To(gomega.ContainElement(
+						gomega.BeComparableTo(metav1.Condition{
+							Type:   "Available",
+							Status: metav1.ConditionTrue,
+							Reason: "AllGroupsReady",
+						}, util.IgnoreConditionTimestampsAndObservedGeneration, util.IgnoreConditionMessage),
+					))
+				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
+			})
+
+			ginkgo.By("Await for the low-priory LeaderWorkerSet to be preempted", func() {
+				createdLowPriorityLWS := &leaderworkersetv1.LeaderWorkerSet{}
+				gomega.Eventually(func(g gomega.Gomega) {
+					g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(lowPriorityLWS), createdLowPriorityLWS)).To(gomega.Succeed())
+					g.Expect(createdLowPriorityLWS.Status.ReadyReplicas).To(gomega.Equal(int32(0)))
+					g.Expect(createdLowPriorityLWS.Status.Conditions).To(gomega.ContainElements(
+						gomega.BeComparableTo(metav1.Condition{
+							Type:   "Progressing",
+							Status: metav1.ConditionTrue,
+							Reason: "GroupsProgressing",
+						}, util.IgnoreConditionTimestampsAndObservedGeneration, util.IgnoreConditionMessage),
+						gomega.BeComparableTo(metav1.Condition{
+							Type:   "Available",
+							Status: metav1.ConditionFalse,
+							Reason: "AllGroupsReady",
+						}, util.IgnoreConditionTimestampsAndObservedGeneration, util.IgnoreConditionMessage),
+					))
+				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
+			})
+
+			createdHighPriorityWl := &kueue.Workload{}
+			highPriorityWlLookupKey := types.NamespacedName{
+				Name:      leaderworkerset.GetWorkloadName(highPriorityLWS.UID, highPriorityLWS.Name, "0"),
+				Namespace: ns.Name,
+			}
+			ginkgo.By("Await for the high priority Workload to be admitted", func() {
+				gomega.Eventually(func(g gomega.Gomega) {
+					g.Expect(k8sClient.Get(ctx, highPriorityWlLookupKey, createdHighPriorityWl)).To(gomega.Succeed())
+					g.Expect(createdHighPriorityWl.Status.Conditions).To(testing.HaveConditionStatusTrue(kueue.WorkloadAdmitted))
+					g.Expect(createdHighPriorityWl.Spec.PriorityClassSource).To(gomega.Equal(constants.WorkloadPriorityClassSource))
+					g.Expect(createdHighPriorityWl.Spec.PriorityClassName).To(gomega.Equal(highPriorityLWS.Name))
+				}, util.Timeout, util.Interval).Should(gomega.Succeed())
+			})
+		})
+	})
 })
diff --git a/test/e2e/singlecluster/statefulset_test.go b/test/e2e/singlecluster/statefulset_test.go
index b32de9492..c62562436 100644
--- a/test/e2e/singlecluster/statefulset_test.go
+++ b/test/e2e/singlecluster/statefulset_test.go
@@ -28,7 +28,8 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta1"
-	"sigs.k8s.io/kueue/pkg/controller/constants"
+	"sigs.k8s.io/kueue/pkg/constants"
+	controllerconstants "sigs.k8s.io/kueue/pkg/controller/constants"
 	"sigs.k8s.io/kueue/pkg/controller/jobs/statefulset"
 	"sigs.k8s.io/kueue/pkg/util/testing"
 	statefulsettesting "sigs.k8s.io/kueue/pkg/util/testingjobs/statefulset"
@@ -362,7 +363,7 @@ var _ = ginkgo.Describe("StatefulSet integration", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					createdStatefulSet := &appsv1.StatefulSet{}
 					g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(statefulSet), createdStatefulSet)).To(gomega.Succeed())
-					createdStatefulSet.Labels[constants.QueueLabel] = localQueueName
+					createdStatefulSet.Labels[controllerconstants.QueueLabel] = localQueueName
 					g.Expect(k8sClient.Update(ctx, createdStatefulSet)).To(gomega.Succeed())
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
@@ -427,4 +428,108 @@ var _ = ginkgo.Describe("StatefulSet integration", func() {
 			})
 		})
 	})
+
+	ginkgo.When("StatefulSet created with WorkloadPriorityClass", func() {
+		var (
+			highPriorityWPC *kueue.WorkloadPriorityClass
+			lowPriorityWPC  *kueue.WorkloadPriorityClass
+		)
+
+		ginkgo.BeforeEach(func() {
+			highPriorityWPC = testing.MakeWorkloadPriorityClass("high-priority").
+				PriorityValue(5000).
+				Obj()
+			gomega.Expect(k8sClient.Create(ctx, highPriorityWPC)).To(gomega.Succeed())
+
+			lowPriorityWPC = testing.MakeWorkloadPriorityClass("low-priority").
+				PriorityValue(1000).
+				Obj()
+			gomega.Expect(k8sClient.Create(ctx, lowPriorityWPC)).To(gomega.Succeed())
+		})
+
+		ginkgo.AfterEach(func() {
+			util.ExpectObjectToBeDeleted(ctx, k8sClient, highPriorityWPC, true)
+			util.ExpectObjectToBeDeleted(ctx, k8sClient, lowPriorityWPC, true)
+		})
+
+		ginkgo.It("should preempt low-priority StatefulSet", func() {
+			lowPrioritySTS := statefulsettesting.MakeStatefulSet("low-priority", ns.Name).
+				Image(util.E2eTestAgnHostImage, util.BehaviorWaitForDeletion).
+				RequestAndLimit(corev1.ResourceCPU, "1").
+				TerminationGracePeriod(1).
+				Replicas(3).
+				Queue(lq.Name).
+				WorkloadPriorityClass(lowPriorityWPC.Name).
+				Obj()
+
+			ginkgo.By("Create a low-priority StatefulSet", func() {
+				gomega.Expect(k8sClient.Create(ctx, lowPrioritySTS)).To(gomega.Succeed())
+			})
+
+			ginkgo.By("Waiting for replicas is ready in low-priority StatefulSet", func() {
+				gomega.Eventually(func(g gomega.Gomega) {
+					createdLowPrioritySTS := &appsv1.StatefulSet{}
+					g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(lowPrioritySTS), createdLowPrioritySTS)).To(gomega.Succeed())
+					g.Expect(createdLowPrioritySTS.Status.ReadyReplicas).To(gomega.Equal(int32(3)))
+				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
+			})
+
+			createdLowPriorityWl := &kueue.Workload{}
+			lowPriorityWlKey := types.NamespacedName{
+				Name:      statefulset.GetWorkloadName(lowPrioritySTS.Name),
+				Namespace: ns.Name,
+			}
+			ginkgo.By("Check the low-priority Workload is created and admitted", func() {
+				gomega.Eventually(func(g gomega.Gomega) {
+					g.Expect(k8sClient.Get(ctx, lowPriorityWlKey, createdLowPriorityWl)).To(gomega.Succeed())
+					g.Expect(createdLowPriorityWl.Spec.PriorityClassSource).To(gomega.Equal(constants.WorkloadPriorityClassSource))
+					g.Expect(createdLowPriorityWl.Spec.PriorityClassName).To(gomega.Equal(lowPriorityWPC.Name))
+					g.Expect(createdLowPriorityWl.Status.Conditions).To(testing.HaveConditionStatusTrue(kueue.WorkloadAdmitted))
+				}, util.Timeout, util.Interval).Should(gomega.Succeed())
+			})
+
+			highPrioritySTS := statefulsettesting.MakeStatefulSet("high-priority", ns.Name).
+				Image(util.E2eTestAgnHostImage, util.BehaviorWaitForDeletion).
+				RequestAndLimit(corev1.ResourceCPU, "1").
+				TerminationGracePeriod(1).
+				Replicas(3).
+				Queue(lq.Name).
+				WorkloadPriorityClass(highPriorityWPC.Name).
+				Obj()
+
+			ginkgo.By("Create a high-priority StatefulSet", func() {
+				gomega.Expect(k8sClient.Create(ctx, highPrioritySTS)).To(gomega.Succeed())
+			})
+
+			ginkgo.By("Waiting for replicas is ready in high-priority StatefulSet", func() {
+				gomega.Eventually(func(g gomega.Gomega) {
+					createdHighPrioritySTS := &appsv1.StatefulSet{}
+					g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(highPrioritySTS), createdHighPrioritySTS)).To(gomega.Succeed())
+					g.Expect(createdHighPrioritySTS.Status.ReadyReplicas).To(gomega.Equal(int32(3)))
+				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
+			})
+
+			ginkgo.By("Await for the low-priory StatefulSet to be preempted", func() {
+				gomega.Eventually(func(g gomega.Gomega) {
+					createdLowPrioritySTS := &appsv1.StatefulSet{}
+					g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(lowPrioritySTS), createdLowPrioritySTS)).To(gomega.Succeed())
+					g.Expect(createdLowPrioritySTS.Status.ReadyReplicas).To(gomega.Equal(int32(0)))
+				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
+			})
+
+			createdHighPriorityWl := &kueue.Workload{}
+			highPriorityWlKey := types.NamespacedName{
+				Name:      statefulset.GetWorkloadName(highPrioritySTS.Name),
+				Namespace: ns.Name,
+			}
+			ginkgo.By("Await for the high-priority Workload to be admitted", func() {
+				gomega.Eventually(func(g gomega.Gomega) {
+					g.Expect(k8sClient.Get(ctx, highPriorityWlKey, createdHighPriorityWl)).To(gomega.Succeed())
+					g.Expect(createdHighPriorityWl.Spec.PriorityClassSource).To(gomega.Equal(constants.WorkloadPriorityClassSource))
+					g.Expect(createdHighPriorityWl.Spec.PriorityClassName).To(gomega.Equal(highPriorityWPC.Name))
+					g.Expect(createdHighPriorityWl.Status.Conditions).To(testing.HaveConditionStatusTrue(kueue.WorkloadAdmitted))
+				}, util.Timeout, util.Interval).Should(gomega.Succeed())
+			})
+		})
+	})
 })
diff --git a/test/e2e/singlecluster/suite_test.go b/test/e2e/singlecluster/suite_test.go
index fc08c99f3..0beeb8b68 100644
--- a/test/e2e/singlecluster/suite_test.go
+++ b/test/e2e/singlecluster/suite_test.go
@@ -63,7 +63,7 @@ var _ = ginkgo.BeforeSuite(func() {
 	restClient = util.CreateRestClient(cfg)
 	visibilityClient = util.CreateVisibilityClient("")
 	impersonatedVisibilityClient = util.CreateVisibilityClient("system:serviceaccount:kueue-system:default")
-	ctx = context.Background()
+	ctx = ginkgo.GinkgoT().Context()
 
 	waitForAvailableStart := time.Now()
 	util.WaitForKueueAvailability(ctx, k8sClient)
diff --git a/test/e2e/tas/rayjob_test.go b/test/e2e/tas/rayjob_test.go
index 284991df7..fba63e48d 100644
--- a/test/e2e/tas/rayjob_test.go
+++ b/test/e2e/tas/rayjob_test.go
@@ -86,8 +86,9 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for RayJob", ginkgo.Ordered, fu
 			const (
 				headReplicas   = 1
 				workerReplicas = 3
+				submitter      = 1
 			)
-			numPods := headReplicas + workerReplicas
+			numPods := headReplicas + workerReplicas + submitter
 			kuberayTestImage := util.GetKuberayTestImage()
 			rayjob := testingrayjob.MakeJob("ranks-ray", ns.Name).
 				Queue(localQueue.Name).
@@ -194,12 +195,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for RayJob", ginkgo.Ordered, fu
 			ginkgo.By("ensure all pods are created", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.List(ctx, pods, client.InNamespace(rayjob.Namespace))).To(gomega.Succeed())
-					// TODO(#4665): strengthen the assert after moving to Ray >=1.3.1.
-					// We temporarily don't assert on the exact number of Pods as this flakes on Ray
-					// 1.2.2 due to the submitter Pod and Job not being created occasionally (See
-					// https://github.com/kubernetes-sigs/kueue/issues/4508#issuecomment-2724257298
-					// for more details).
-					g.Expect(len(pods.Items)).Should(gomega.BeNumerically(">=", numPods))
+					g.Expect(pods.Items).Should(gomega.HaveLen(numPods))
 					// The timeout is long to ensure all cluster pods are up and running.
 					// This is because the Ray image takes long time (around 170s on the CI)
 					// to load and then to sync with head.
diff --git a/test/e2e/tas/suite_test.go b/test/e2e/tas/suite_test.go
index 717b18c45..50265cf6b 100644
--- a/test/e2e/tas/suite_test.go
+++ b/test/e2e/tas/suite_test.go
@@ -53,7 +53,7 @@ var _ = ginkgo.BeforeSuite(func() {
 	util.SetupLogger()
 
 	k8sClient, _ = util.CreateClientUsingCluster("")
-	ctx = context.Background()
+	ctx = ginkgo.GinkgoT().Context()
 
 	waitForAvailableStart := time.Now()
 	util.WaitForKueueAvailability(ctx, k8sClient)
diff --git a/test/integration/framework/framework.go b/test/integration/framework/framework.go
index 3c7ac6c50..2a5f4a194 100644
--- a/test/integration/framework/framework.go
+++ b/test/integration/framework/framework.go
@@ -133,7 +133,7 @@ func (f *Framework) SetupClient(cfg *rest.Config) (context.Context, client.Clien
 	gomega.ExpectWithOffset(1, err).NotTo(gomega.HaveOccurred())
 	gomega.ExpectWithOffset(1, k8sClient).NotTo(gomega.BeNil())
 
-	ctx, cancel := context.WithCancel(context.Background())
+	ctx, cancel := context.WithCancel(ginkgo.GinkgoT().Context())
 	f.cancel = cancel
 
 	return ctx, k8sClient
diff --git a/test/integration/singlecluster/scheduler/fairsharing/fair_sharing_test.go b/test/integration/singlecluster/scheduler/fairsharing/fair_sharing_test.go
index 316c7a99c..6a92c6108 100644
--- a/test/integration/singlecluster/scheduler/fairsharing/fair_sharing_test.go
+++ b/test/integration/singlecluster/scheduler/fairsharing/fair_sharing_test.go
@@ -23,6 +23,7 @@ import (
 	"github.com/onsi/gomega"
 	corev1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/api/meta"
+	"k8s.io/apimachinery/pkg/api/resource"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/types"
 	"k8s.io/apimachinery/pkg/util/sets"
@@ -66,8 +67,9 @@ var _ = ginkgo.Describe("Scheduler", func() {
 		return cq
 	}
 
-	var createWorkload = func(queue string, cpuRequests string) *kueue.Workload {
+	var createWorkloadWithPriority = func(queue string, cpuRequests string, priority int32) *kueue.Workload {
 		wl := testing.MakeWorkloadWithGeneratedName("workload-", ns.Name).
+			Priority(priority).
 			Queue(queue).
 			Request(corev1.ResourceCPU, cpuRequests).Obj()
 		wls = append(wls, wl)
@@ -75,6 +77,10 @@ var _ = ginkgo.Describe("Scheduler", func() {
 		return wl
 	}
 
+	var createWorkload = func(queue string, cpuRequests string) *kueue.Workload {
+		return createWorkloadWithPriority(queue, cpuRequests, 0)
+	}
+
 	ginkgo.BeforeEach(func() {
 		defaultFlavor = testing.MakeResourceFlavor("default").Obj()
 		gomega.Expect(k8sClient.Create(ctx, defaultFlavor)).To(gomega.Succeed())
@@ -328,6 +334,70 @@ var _ = ginkgo.Describe("Scheduler", func() {
 			expectCohortWeightedShare(cohortSecondRight.Name, 214)
 			expectCohortWeightedShare(cohortBank.Name, 0)
 		})
+		ginkgo.It("preempts workloads to enforce fair share", func() {
+			// below are Cohorts and their fair
+			// weights. 12 CPUs are provided by the root
+			// Cohort
+			//            root
+			//          /      \
+			//        /          \
+			// best-effort(0.5)  research
+			//                   /   |    \
+			//                  /    |     \
+			//          chemistry  physics   llm(2.0)
+			createCohort(testing.MakeCohort("root").ResourceGroup(*testing.MakeFlavorQuotas("default").Resource(corev1.ResourceCPU, "12").Obj()).Obj())
+			createCohort(testing.MakeCohort("research").Parent("root").Obj())
+			createCohort(testing.MakeCohort("chemistry").Parent("research").Obj())
+			createCohort(testing.MakeCohort("physics").Parent("research").Obj())
+			createCohort(testing.MakeCohort("llm").FairWeight(resource.MustParse("2.0")).Parent("research").Obj())
+			createCohort(testing.MakeCohort("best-effort").FairWeight(resource.MustParse("0.5")).Parent("root").Obj())
+
+			preemptionPolicy := kueue.ClusterQueuePreemption{
+				ReclaimWithinCohort: kueue.PreemptionPolicyLowerPriority,
+			}
+			zeroQuota := *testing.MakeFlavorQuotas("default").Resource(corev1.ResourceCPU, "0").Obj()
+
+			chemistryQueue := createQueue(testing.MakeClusterQueue("chemistry-queue").Cohort("chemistry").ResourceGroup(zeroQuota).Preemption(preemptionPolicy).Obj())
+			physicsQueue := createQueue(testing.MakeClusterQueue("physics-queue").Cohort("physics").ResourceGroup(zeroQuota).Preemption(preemptionPolicy).Obj())
+			llmQueue := createQueue(testing.MakeClusterQueue("llm-queue").Cohort("llm").ResourceGroup(zeroQuota).Preemption(preemptionPolicy).Obj())
+			bestEffortQueue := createQueue(testing.MakeClusterQueue("best-effort-queue").Cohort("best-effort").ResourceGroup(zeroQuota).Obj())
+
+			ginkgo.By("all capacity used")
+			for range 6 {
+				createWorkloadWithPriority(bestEffortQueue.GetName(), "1", -1)
+				createWorkloadWithPriority(physicsQueue.GetName(), "1", -1)
+			}
+			expectCohortWeightedShare("best-effort", 1000)
+			expectCohortWeightedShare("physics", 500)
+			util.ExpectReservingActiveWorkloadsMetric(bestEffortQueue, 6)
+			util.ExpectReservingActiveWorkloadsMetric(physicsQueue, 6)
+
+			ginkgo.By("create high priority workloads")
+			for range 6 {
+				for _, cq := range cqs {
+					createWorkloadWithPriority(cq.GetName(), "1", 100)
+				}
+			}
+
+			ginkgo.By("preempt workloads")
+			finishEvictionOfWorkloadsInCQ(bestEffortQueue, 2)
+			finishEvictionOfWorkloadsInCQ(physicsQueue, 4)
+
+			ginkgo.By("share is fair with respect to each parent")
+			// parent root
+			expectCohortWeightedShare("best-effort", 666)
+			expectCohortWeightedShare("research", 666)
+			// parent research
+			expectCohortWeightedShare("chemistry", 166)
+			expectCohortWeightedShare("physics", 166)
+			expectCohortWeightedShare("llm", 166)
+
+			ginkgo.By("number workloads admitted proportional to share at each level")
+			util.ExpectReservingActiveWorkloadsMetric(bestEffortQueue, 4)
+			util.ExpectReservingActiveWorkloadsMetric(chemistryQueue, 2)
+			util.ExpectReservingActiveWorkloadsMetric(physicsQueue, 2)
+			util.ExpectReservingActiveWorkloadsMetric(llmQueue, 4)
+		})
 	})
 })
 
diff --git a/test/integration/singlecluster/scheduler/scheduler_test.go b/test/integration/singlecluster/scheduler/scheduler_test.go
index 5f4f79dc4..af3d822fd 100644
--- a/test/integration/singlecluster/scheduler/scheduler_test.go
+++ b/test/integration/singlecluster/scheduler/scheduler_test.go
@@ -1671,14 +1671,7 @@ var _ = ginkgo.Describe("Scheduler", func() {
 				Cohort(chName).
 				Obj()
 			gomega.Expect(k8sClient.Create(ctx, strictFIFOClusterQ)).Should(gomega.Succeed())
-			matchingNS = &corev1.Namespace{
-				ObjectMeta: metav1.ObjectMeta{
-					GenerateName: "foo-",
-					Labels:       map[string]string{"dep": "eng"},
-				},
-			}
-			ginkgo.By(fmt.Sprintf("Creating namespace: %s", matchingNS.Name))
-			gomega.Expect(k8sClient.Create(ctx, matchingNS)).To(gomega.Succeed())
+			matchingNS = util.CreateNamespaceFromObjectWithLog(ctx, k8sClient, testing.MakeNamespaceWrapper("").GenerateName("foo-").Label("dep", "eng").Obj())
 		})
 
 		ginkgo.AfterEach(func() {
diff --git a/test/util/e2e.go b/test/util/e2e.go
index ce9a43891..93eb61aa7 100644
--- a/test/util/e2e.go
+++ b/test/util/e2e.go
@@ -312,16 +312,16 @@ func GetKuberayTestImage() string {
 
 func CreateNamespaceWithLog(ctx context.Context, k8sClient client.Client, nsName string) *corev1.Namespace {
 	ginkgo.GinkgoHelper()
-	ns := utiltesting.MakeNamespace(nsName)
-	gomega.Expect(k8sClient.Create(ctx, ns)).To(gomega.Succeed())
-	ginkgo.GinkgoLogr.Info(fmt.Sprintf("Created namespace: %s", ns.Name))
-	return ns
+	return CreateNamespaceFromObjectWithLog(ctx, k8sClient, utiltesting.MakeNamespace(nsName))
 }
 
 func CreateNamespaceFromPrefixWithLog(ctx context.Context, k8sClient client.Client, nsPrefix string) *corev1.Namespace {
 	ginkgo.GinkgoHelper()
-	ns := utiltesting.MakeNamespaceWithGenerateName(nsPrefix)
-	gomega.Expect(k8sClient.Create(ctx, ns)).To(gomega.Succeed())
+	return CreateNamespaceFromObjectWithLog(ctx, k8sClient, utiltesting.MakeNamespaceWithGenerateName(nsPrefix))
+}
+
+func CreateNamespaceFromObjectWithLog(ctx context.Context, k8sClient client.Client, ns *corev1.Namespace) *corev1.Namespace {
+	gomega.ExpectWithOffset(1, k8sClient.Create(ctx, ns)).To(gomega.Succeed())
 	ginkgo.GinkgoLogr.Info(fmt.Sprintf("Created namespace: %s", ns.Name))
 	return ns
 }