Repository: kubernetes-sigs/kueue

Issue:
Flaky Test: TopologyAwareScheduling for RayJob when Creating a RayJob Should place pods based on the ranks-ordering
<!-- Please use this template while reporting a bug and provide as much info as possible. Not doing so may result in your bug not being addressed in a timely manner. Thanks!

If the matter is security related, please disclose it privately via https://kubernetes.io/security/
-->


**What happened**:
Failed the `End To End TAS Suite: kindest/node:v1.31.1: [It] TopologyAwareScheduling for RayJob when Creating a RayJob Should place pods based on the ranks-ordering` in periodic CI

```shell
{Timed out after 300.000s.
The function passed to Eventually failed at /home/prow/go/src/kubernetes-sigs/kueue/test/e2e/tas/rayjob_test.go:203 with:
Expected
    <[]v1.Pod | len:4, cap:4>: [
        {
            TypeMeta: {Kind: "", APIVersion: ""},
            ObjectMeta: {
                Name: "ranks-ray-raycluster-gpzrs-head-mm657",
                GenerateName: "ranks-ray-raycluster-gpzrs-head-",
                Namespace: "e2e-tas-rayjob-lgmbj",
                SelfLink: "",
                UID: "cbf00188-3d57-4dce-a72c-3c6827775792",
                ResourceVersion: "4265",
                Generation: 0,
                CreationTimestamp: {
                    Time: 2025-03-05T22:40:41Z,
                },
                DeletionTimestamp: nil,
                DeletionGracePeriodSeconds: nil,
                Labels: {
                    "kueue.x-k8s.io/tas": "true",
                    "ray.io/group": "headgroup",
                    "ray.io/identifier": "ranks-ray-raycluster-gpzrs-head",
                    "ray.io/is-ray-node": "yes",
                    "app.kubernetes.io/created-by": "kuberay-operator",
                    "kueue.x-k8s.io/podset": "head",
                    "ray.io/cluster": "ranks-ray-raycluster-gpzrs",
                    "ray.io/node-type": "head",
                    "app.kubernetes.io/name": "kuberay",
                },
                Annotations: {
                    "kueue.x-k8s.io/podset-preferred-topology": "cloud.provider.com/topology-rack",
                    "kueue.x-k8s.io/workload": "rayjob-ranks-ray-8120c",
                    "ray.io/ft-enabled": "false",
                },
                OwnerReferences: [
                    {
                        APIVersion: "ray.io/v1",
                        Kind: "RayCluster",
                        Name: "ranks-ray-raycluster-gpzrs",
                        UID: "0616b0a6-e920-481b-9516-db1f0880f2b1",
                        Controller: true,
                        BlockOwnerDeletion: true,
                    },
                ],
                Finalizers: nil,
                ManagedFields: [
                    {
                        Manager: "kuberay-operator",
                        Operation: "Update",
                        APIVersion: "v1",
                        Time: {
                            Time: 2025-03-05T22:40:41Z,
                        },
                        FieldsType: "FieldsV1",
                        FieldsV1: {
                            Raw: "{\"f:metadata\":{\"f:annotations\":{\".\":{},\"f:kueue.x-k8s.io/podset-preferred-topology\":{},\"f:kueue.x-k8s.io/workload\":{},\"f:ray.io/ft-enabled\":{}},\"f:generateName\":{},\"f:labels\":{\".\":{},\"f:app.kubernetes.io/created-by\":{},\"f:app.kubernetes.io/name\":{},\"f:kueue.x-k8s.io/podset\":{},\"f:kueue.x-k8s.io/tas\":{},\"f:ray.io/cluster\":{},\"f:ray.io/group\":{},\"f:ray.io/identifier\":{},\"f:ray.io/is-ray-node\":{},\"f:ray.io/node-type\":{}},\"f:ownerReferences\":{\".\":{},\"k:{\\\"uid\\\":\\\"0616b0a6-e920-481b-9516-db1f0880f2b1\\\"}\":{}}},\"f:spec\":{\"f:containers\":{\"k:{\\\"name\\\":\\\"head-container\\\"}\":{\".\":{},\"f:args\":{},\"f:command\":{},\"f:env\":{\".\":{},\"k:{\\\"name\\\":\\\"KUBERAY_GEN_RAY_START_CMD\\\"}\":{\".\":{},\"f:name\":{},\"f:value\":{}},\"k:{\\\"name\\\":\\\"RAY_ADDRESS\\\"}\":{\".\":{},\"f:name\":{},\"f:value\":{}},\"k:{\\\"name\\\":\\\"RAY_CLOUD_INSTANCE_ID\\\"}\":{\".\":{},\"f:name\":{},\"f:valueFrom\":{\".\":{},\"f:fieldRef\":{}}},\"k:{\\\"name\\\":\\\"RAY_CLUSTER_NAME\\\"}\":{\".\":{},\"f:name\":{},\"f:valueFrom\":{\".\":{},\"f:fieldRef\":{}}},\"k:{\\\"name\\\":\\\"RAY_DASHBOARD_ENABLE_K8S_DISK_USAGE\\\"}\":{\".\":{},\"f:name\":{},\"f:value\":{}},\"k:{\\\"name\\\":\\\"RAY_NODE_TYPE_NAME\\\"}\":{\".\":{},\"f:name\":{},\"f:valueFrom\":{\".\":{},\"f:fieldRef\":{}}},\"k:{\\\"name\\\":\\\"RAY_PORT\\\"}\":{\".\":{},\"f:name\":{},\"f:value\":{}},\"k:{\\\"name\\\":\\\"RAY_USAGE_STATS_EXTRA_TAGS\\\"}\":{\".\":{},\"f:name\":{},\"f:value\":{}},\"k:{\\\"name\\\":\\\"RAY_USAGE_STATS_KUBERAY_IN_USE\\\"}\":{\".\":{},\"f:name\":{},\"f:value\":{}},\"k:{\\\"name\\\":\\\"REDIS_PASSWORD\\\"}\":{\".\":{},\"f...

Gomega truncated this representation as it exceeds 'format.MaxLength'.
Consider having the object provide a custom 'GomegaStringer' representation
or adjust the parameters in Gomega's 'format' package.

Learn more here: https://onsi.github.io/gomega/#adjusting-output

to have length 5 failed [FAILED] Timed out after 300.000s.
The function passed to Eventually failed at /home/prow/go/src/kubernetes-sigs/kueue/test/e2e/tas/rayjob_test.go:203 with:
Expected
    <[]v1.Pod | len:4, cap:4>: [
        {
            TypeMeta: {Kind: "", APIVersion: ""},
            ObjectMeta: {
                Name: "ranks-ray-raycluster-gpzrs-head-mm657",
                GenerateName: "ranks-ray-raycluster-gpzrs-head-",
                Namespace: "e2e-tas-rayjob-lgmbj",
                SelfLink: "",
                UID: "cbf00188-3d57-4dce-a72c-3c6827775792",
                ResourceVersion: "4265",
                Generation: 0,
                CreationTimestamp: {
                    Time: 2025-03-05T22:40:41Z,
                },
                DeletionTimestamp: nil,
                DeletionGracePeriodSeconds: nil,
                Labels: {
                    "kueue.x-k8s.io/tas": "true",
                    "ray.io/group": "headgroup",
                    "ray.io/identifier": "ranks-ray-raycluster-gpzrs-head",
                    "ray.io/is-ray-node": "yes",
                    "app.kubernetes.io/created-by": "kuberay-operator",
                    "kueue.x-k8s.io/podset": "head",
                    "ray.io/cluster": "ranks-ray-raycluster-gpzrs",
                    "ray.io/node-type": "head",
                    "app.kubernetes.io/name": "kuberay",
                },
                Annotations: {
                    "kueue.x-k8s.io/podset-preferred-topology": "cloud.provider.com/topology-rack",
                    "kueue.x-k8s.io/workload": "rayjob-ranks-ray-8120c",
                    "ray.io/ft-enabled": "false",
                },
                OwnerReferences: [
                    {
                        APIVersion: "ray.io/v1",
                        Kind: "RayCluster",
                        Name: "ranks-ray-raycluster-gpzrs",
                        UID: "0616b0a6-e920-481b-9516-db1f0880f2b1",
                        Controller: true,
                        BlockOwnerDeletion: true,
                    },
                ],
                Finalizers: nil,
                ManagedFields: [
                    {
                        Manager: "kuberay-operator",
                        Operation: "Update",
                        APIVersion: "v1",
                        Time: {
                            Time: 2025-03-05T22:40:41Z,
                        },
                        FieldsType: "FieldsV1",
                        FieldsV1: {
                            Raw: "{\"f:metadata\":{\"f:annotations\":{\".\":{},\"f:kueue.x-k8s.io/podset-preferred-topology\":{},\"f:kueue.x-k8s.io/workload\":{},\"f:ray.io/ft-enabled\":{}},\"f:generateName\":{},\"f:labels\":{\".\":{},\"f:app.kubernetes.io/created-by\":{},\"f:app.kubernetes.io/name\":{},\"f:kueue.x-k8s.io/podset\":{},\"f:kueue.x-k8s.io/tas\":{},\"f:ray.io/cluster\":{},\"f:ray.io/group\":{},\"f:ray.io/identifier\":{},\"f:ray.io/is-ray-node\":{},\"f:ray.io/node-type\":{}},\"f:ownerReferences\":{\".\":{},\"k:{\\\"uid\\\":\\\"0616b0a6-e920-481b-9516-db1f0880f2b1\\\"}\":{}}},\"f:spec\":{\"f:containers\":{\"k:{\\\"name\\\":\\\"head-container\\\"}\":{\".\":{},\"f:args\":{},\"f:command\":{},\"f:env\":{\".\":{},\"k:{\\\"name\\\":\\\"KUBERAY_GEN_RAY_START_CMD\\\"}\":{\".\":{},\"f:name\":{},\"f:value\":{}},\"k:{\\\"name\\\":\\\"RAY_ADDRESS\\\"}\":{\".\":{},\"f:name\":{},\"f:value\":{}},\"k:{\\\"name\\\":\\\"RAY_CLOUD_INSTANCE_ID\\\"}\":{\".\":{},\"f:name\":{},\"f:valueFrom\":{\".\":{},\"f:fieldRef\":{}}},\"k:{\\\"name\\\":\\\"RAY_CLUSTER_NAME\\\"}\":{\".\":{},\"f:name\":{},\"f:valueFrom\":{\".\":{},\"f:fieldRef\":{}}},\"k:{\\\"name\\\":\\\"RAY_DASHBOARD_ENABLE_K8S_DISK_USAGE\\\"}\":{\".\":{},\"f:name\":{},\"f:value\":{}},\"k:{\\\"name\\\":\\\"RAY_NODE_TYPE_NAME\\\"}\":{\".\":{},\"f:name\":{},\"f:valueFrom\":{\".\":{},\"f:fieldRef\":{}}},\"k:{\\\"name\\\":\\\"RAY_PORT\\\"}\":{\".\":{},\"f:name\":{},\"f:value\":{}},\"k:{\\\"name\\\":\\\"RAY_USAGE_STATS_EXTRA_TAGS\\\"}\":{\".\":{},\"f:name\":{},\"f:value\":{}},\"k:{\\\"name\\\":\\\"RAY_USAGE_STATS_KUBERAY_IN_USE\\\"}\":{\".\":{},\"f:name\":{},\"f:value\":{}},\"k:{\\\"name\\\":\\\"REDIS_PASSWORD\\\"}\":{\".\":{},\"f...

Gomega truncated this representation as it exceeds 'format.MaxLength'.
Consider having the object provide a custom 'GomegaStringer' representation
or adjust the parameters in Gomega's 'format' package.

Learn more here: https://onsi.github.io/gomega/#adjusting-output

to have length 5
In [It] at: /home/prow/go/src/kubernetes-sigs/kueue/test/e2e/tas/rayjob_test.go:207 @ 03/05/25 22:45:41.951
}
```

**What you expected to happen**:
No errors

**How to reproduce it (as minimally and precisely as possible)**:

https://prow.k8s.io/view/gs/kubernetes-ci-logs/logs/periodic-kueue-test-e2e-tas-main/1897412525620727808

<img width="1261" alt="Image" src="https://github.com/user-attachments/assets/514c7460-678d-4d9c-b04f-c6df0a12789a" />

**Anything else we need to know?**:

**Environment**:
- Kubernetes version (use `kubectl version`):
- Kueue version (use `git describe --tags --dirty --always`):
- Cloud provider or hardware configuration:
- OS (e.g: `cat /etc/os-release`):
- Kernel (e.g. `uname -a`):
- Install tools:
- Others:

Hints from issue comments:
@mbobrovskyi: cc: @mszadkow @mimowo: btw, the error log is truncated. I suppose one of the pods failed for some reason (and was replaced - this is why we had 5 pods). To investigate this one could follow steps similar to https://github.com/kubernetes-sigs/kueue/issues/4495. 

However, another improvement would be to increase the MaxLength for the output - currently it is too short to fit even a single Pod with status - and the status would be the most relevant case here. 

I will open a dedicated issue for that.@mimowo: Opened: https://github.com/kubernetes-sigs/kueue/issues/4509@mszadkow: /assign@mszadkow: This timeout again after the increase to 5 minutes...that's weird, we need to have better insight when it fails, agree@mimowo: I think the key thing is that for some reason there was 5 pods, so probably one failed and was replaced. Try to identify the failed pod, then inspect its container logs, and logs of kubelet related to the pod (assuming the pod failure is the reason here).@mimowo: This seems like another occurrence, but on 0.10 branch: https://prow.k8s.io/view/gs/kubernetes-ci-logs/logs/periodic-kueue-test-e2e-tas-release-0-10/1898862090471346176@mszadkow: Ack, actively investigating this@mimowo: fyi, one more: https://prow.k8s.io/view/gs/kubernetes-ci-logs/pr-logs/pull/kubernetes-sigs_kueue/4524/pull-kueue-test-e2e-tas-main/1899040138269298688. Seems quite often recently@mbobrovskyi: one more: https://prow.k8s.io/view/gs/kubernetes-ci-logs/pr-logs/pull/kubernetes-sigs_kueue/4585/pull-kueue-test-e2e-tas-main/1900113461916995584@mszadkow: For this one I think we might want to change the approach.
This submitter job created by rayJob might be short lived and fall into the gap of interval.
What if we check ray cluster nodes, but later verify rayJob status, that should change after the submitter is finished anyway.
This could make it less flaky for tests while we still prove sanity of the RayJob with tas@mimowo: I looked into the Ray failures too

First, the tests fail expecting 5 pods, but they only observe 4. Looking at the API server logs we can confirm that RayOperator only created 4:

```
> cat api.log | grep e2e-tas-rayjob-lgmbj/pods | grep POST | grep 201
2025-03-05T22:40:41.977203895Z stderr F I0305 22:40:41.976983       1 httplog.go:134] "HTTP" verb="POST" URI="/api/v1/namespaces/e2e-tas-rayjob-lgmbj/pods" latency="11.586316ms" userAgent="kuberay-operator/v1.2.2" audit-ID="33e27fd2-d22d-4c4d-9b46-d4efeca06f05" srcIP="172.18.0.5:37344" apf_pl="workload-low" apf_fs="service-accounts" apf_iseats=1 apf_fseats=2 apf_additionalLatency="5ms" apf_execution_time="11.024848ms" resp=201
2025-03-05T22:40:42.025410431Z stderr F I0305 22:40:42.025081       1 httplog.go:134] "HTTP" verb="POST" URI="/api/v1/namespaces/e2e-tas-rayjob-lgmbj/pods" latency="8.426362ms" userAgent="kuberay-operator/v1.2.2" audit-ID="4d674538-ad9c-45f4-b055-dff0bd1db0a2" srcIP="172.18.0.5:37344" apf_pl="workload-low" apf_fs="service-accounts" apf_iseats=1 apf_fseats=2 apf_additionalLatency="5ms" apf_execution_time="8.135949ms" resp=201
2025-03-05T22:40:42.035689969Z stderr F I0305 22:40:42.035397       1 httplog.go:134] "HTTP" verb="POST" URI="/api/v1/namespaces/e2e-tas-rayjob-lgmbj/pods" latency="8.717217ms" userAgent="kuberay-operator/v1.2.2" audit-ID="42111a1c-315b-47bc-a77a-aeefaa2310c2" srcIP="172.18.0.5:37344" apf_pl="workload-low" apf_fs="service-accounts" apf_iseats=1 apf_fseats=2 apf_additionalLatency="5ms" apf_execution_time="8.339393ms" resp=201
2025-03-05T22:40:42.124730152Z stderr F I0305 22:40:42.124491       1 httplog.go:134] "HTTP" verb="POST" URI="/api/v1/namespaces/e2e-tas-rayjob-lgmbj/pods" latency="8.2536ms" userAgent="kuberay-operator/v1.2.2" audit-ID="fab4d7eb-ff9a-40cc-8cb1-d75d56f50c29" srcIP="172.18.0.5:37344" apf_pl="workload-low" apf_fs="service-accounts" apf_iseats=1 apf_fseats=2 apf_additionalLatency="5ms" apf_execution_time="7.949246ms" resp=201
2025-03-05T22:40:42.999711374Z stderr F I0305 22:40:42.999502       1 httplog.go:134] "HTTP" verb="POST" URI="/api/v1/namespaces/e2e-tas-rayjob-lgmbj/pods/ranks-ray-raycluster-gpzrs-head-mm657/binding" latency="3.6966ms" userAgent="kube-scheduler/v1.31.1 (linux/amd64) kubernetes/948afe5/scheduler" audit-ID="1af828d9-206a-4a8a-babe-407f9529889f" srcIP="172.18.0.4:40688" apf_pl="workload-high" apf_fs="kube-scheduler" apf_iseats=1 apf_fseats=2 apf_additionalLatency="5ms" apf_execution_time="3.282724ms" resp=201
2025-03-05T22:40:42.999746864Z stderr F I0305 22:40:42.999677       1 httplog.go:134] "HTTP" verb="POST" URI="/api/v1/namespaces/e2e-tas-rayjob-lgmbj/pods/ranks-ray-raycluster-gpzrs-workers-group-0-worker-d97p4/binding" latency="3.335175ms" userAgent="kube-scheduler/v1.31.1 (linux/amd64) kubernetes/948afe5/scheduler" audit-ID="402af477-ddef-48ea-9fcf-19f58cf7eb3f" srcIP="172.18.0.4:40688" apf_pl="workload-high" apf_fs="kube-scheduler" apf_iseats=1 apf_fseats=2 apf_additionalLatency="5ms" apf_execution_time="2.960229ms" resp=201
2025-03-05T22:40:43.000747168Z stderr F I0305 22:40:43.000337       1 httplog.go:134] "HTTP" verb="POST" URI="/api/v1/namespaces/e2e-tas-rayjob-lgmbj/pods/ranks-ray-raycluster-gpzrs-workers-group-0-worker-4g6fc/binding" latency="2.859619ms" userAgent="kube-scheduler/v1.31.1 (linux/amd64) kubernetes/948afe5/scheduler" audit-ID="fe2da5fa-309d-4575-91d1-40d63398db2b" srcIP="172.18.0.4:40688" apf_pl="workload-high" apf_fs="kube-scheduler" apf_iseats=1 apf_fseats=2 apf_additionalLatency="5ms" apf_execution_time="2.503914ms" resp=201
2025-03-05T22:40:43.002457031Z stderr F I0305 22:40:43.002218       1 httplog.go:134] "HTTP" verb="POST" URI="/api/v1/namespaces/e2e-tas-rayjob-lgmbj/pods/ranks-ray-raycluster-gpzrs-workers-group-0-worker-zqfwn/binding" latency="4.112935ms" userAgent="kube-scheduler/v1.31.1 (linux/amd64) kubernetes/948afe5/scheduler" audit-ID="54c48759-ad7b-4b77-b91e-a565ded1429b" srcIP="172.18.0.4:40688" apf_pl="workload-high" apf_fs="kube-scheduler" apf_iseats=1 apf_fseats=2 apf_additionalLatency="5ms" apf_execution_time="3.769201ms" resp=201
```
Also `> cat api.log | grep e2e-tas-rayjob-lgmbj/jobs | grep POST | grep 201` returns empty indicating the Submitter Job was never created.

To give more context I grepped the kuberay operator logs which show some errors:
```
> cat ray.log | grep e2e-tas-rayjob-lgmbj               
2025-03-05T22:40:41.691025738Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.690Z","logger":"controllers.RayJob","msg":"RayJob","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"5a22cd41-3f27-4aa3-8a54-d8e1735be202","name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj","JobStatus":"","JobDeploymentStatus":"","SubmissionMode":"K8sJobMode"}
2025-03-05T22:40:41.691074429Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.690Z","logger":"controllers.RayJob","msg":"Add a finalizer","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"5a22cd41-3f27-4aa3-8a54-d8e1735be202","finalizer":"ray.io/rayjob-finalizer"}
2025-03-05T22:40:41.730733001Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.730Z","logger":"controllers.RayJob","msg":"JobDeploymentStatusNew","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"5a22cd41-3f27-4aa3-8a54-d8e1735be202","RayJob":"ranks-ray"}
2025-03-05T22:40:41.730743501Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.730Z","logger":"controllers.RayJob","msg":"initRayJobStatusIfNeed","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"5a22cd41-3f27-4aa3-8a54-d8e1735be202","shouldUpdateStatus":true,"RayJob":"ranks-ray","jobId":"","rayClusterName":"","jobStatus":""}
2025-03-05T22:40:41.730750971Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.730Z","logger":"controllers.RayJob","msg":"updateRayJobStatus","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"5a22cd41-3f27-4aa3-8a54-d8e1735be202","oldRayJobStatus":{"rayClusterStatus":{"desiredCPU":"0","desiredMemory":"0","desiredGPU":"0","desiredTPU":"0","head":{}}},"newRayJobStatus":{"jobId":"ranks-ray-cmmqx","rayClusterName":"ranks-ray-raycluster-sr57x","jobDeploymentStatus":"Initializing","startTime":"2025-03-05T22:40:41Z","succeeded":0,"failed":0,"rayClusterStatus":{"desiredCPU":"0","desiredMemory":"0","desiredGPU":"0","desiredTPU":"0","head":{}}}}
2025-03-05T22:40:41.730781381Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.730Z","logger":"controllers.RayJob","msg":"updateRayJobStatus","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"5a22cd41-3f27-4aa3-8a54-d8e1735be202","old JobStatus":"","new JobStatus":"","old JobDeploymentStatus":"","new JobDeploymentStatus":"Initializing"}
2025-03-05T22:40:41.74035455Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.740Z","logger":"controllers.RayJob","msg":"RayJob","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"82ef785a-2582-44f0-87d6-d131e2ddee90","name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj","JobStatus":"","JobDeploymentStatus":"","SubmissionMode":"K8sJobMode"}
2025-03-05T22:40:41.74038324Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.740Z","logger":"controllers.RayJob","msg":"JobDeploymentStatusNew","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"82ef785a-2582-44f0-87d6-d131e2ddee90","RayJob":"ranks-ray"}
2025-03-05T22:40:41.74039279Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.740Z","logger":"controllers.RayJob","msg":"initRayJobStatusIfNeed","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"82ef785a-2582-44f0-87d6-d131e2ddee90","shouldUpdateStatus":true,"RayJob":"ranks-ray","jobId":"","rayClusterName":"","jobStatus":""}
2025-03-05T22:40:41.740412Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.740Z","logger":"controllers.RayJob","msg":"updateRayJobStatus","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"82ef785a-2582-44f0-87d6-d131e2ddee90","oldRayJobStatus":{"rayClusterStatus":{"desiredCPU":"0","desiredMemory":"0","desiredGPU":"0","desiredTPU":"0","head":{}}},"newRayJobStatus":{"jobId":"ranks-ray-qcdv2","rayClusterName":"ranks-ray-raycluster-669x2","jobDeploymentStatus":"Initializing","startTime":"2025-03-05T22:40:41Z","succeeded":0,"failed":0,"rayClusterStatus":{"desiredCPU":"0","desiredMemory":"0","desiredGPU":"0","desiredTPU":"0","head":{}}}}
2025-03-05T22:40:41.74041605Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.740Z","logger":"controllers.RayJob","msg":"updateRayJobStatus","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"82ef785a-2582-44f0-87d6-d131e2ddee90","old JobStatus":"","new JobStatus":"","old JobDeploymentStatus":"","new JobDeploymentStatus":"Initializing"}
2025-03-05T22:40:41.747129491Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.746Z","logger":"controllers.RayJob","msg":"Failed to update RayJob status","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"82ef785a-2582-44f0-87d6-d131e2ddee90","error":"Operation cannot be fulfilled on rayjobs.ray.io \"ranks-ray\": the object has been modified; please apply your changes to the latest version and try again"}
2025-03-05T22:40:41.747149781Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.747Z","logger":"controllers.RayJob","msg":"Warning: Reconciler returned both a non-zero result and a non-nil error. The result will always be ignored if the error is non-nil and the non-nil error causes reqeueuing with exponential backoff. For more details, see: https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/reconcile#Reconciler","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"82ef785a-2582-44f0-87d6-d131e2ddee90"}
2025-03-05T22:40:41.747178671Z stderr F {"level":"error","ts":"2025-03-05T22:40:41.747Z","logger":"controllers.RayJob","msg":"Reconciler error","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"82ef785a-2582-44f0-87d6-d131e2ddee90","error":"Operation cannot be fulfilled on rayjobs.ray.io \"ranks-ray\": the object has been modified; please apply your changes to the latest version and try again","stacktrace":"sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).reconcileHandler\n\t/home/runner/go/pkg/mod/sigs.k8s.io/controller-runtime@v0.17.5/pkg/internal/controller/controller.go:329\nsigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).processNextWorkItem\n\t/home/runner/go/pkg/mod/sigs.k8s.io/controller-runtime@v0.17.5/pkg/internal/controller/controller.go:266\nsigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).Start.func2.2\n\t/home/runner/go/pkg/mod/sigs.k8s.io/controller-runtime@v0.17.5/pkg/internal/controller/controller.go:227"}
2025-03-05T22:40:41.747340263Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.747Z","logger":"controllers.RayJob","msg":"RayJob","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"9ea0d50f-11cb-4f19-b0f9-67d9fae463b5","name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj","JobStatus":"","JobDeploymentStatus":"Initializing","SubmissionMode":"K8sJobMode"}
2025-03-05T22:40:41.747351023Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.747Z","logger":"controllers.RayJob","msg":"Try to transition the status from `Initializing` to `Suspending`","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"9ea0d50f-11cb-4f19-b0f9-67d9fae463b5","RayJob":"ranks-ray"}
2025-03-05T22:40:41.747357754Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.747Z","logger":"controllers.RayJob","msg":"updateRayJobStatus","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"9ea0d50f-11cb-4f19-b0f9-67d9fae463b5","oldRayJobStatus":{"jobId":"ranks-ray-cmmqx","rayClusterName":"ranks-ray-raycluster-sr57x","jobDeploymentStatus":"Initializing","startTime":"2025-03-05T22:40:41Z","succeeded":0,"failed":0,"rayClusterStatus":{"desiredCPU":"0","desiredMemory":"0","desiredGPU":"0","desiredTPU":"0","head":{}}},"newRayJobStatus":{"jobId":"ranks-ray-cmmqx","rayClusterName":"ranks-ray-raycluster-sr57x","jobDeploymentStatus":"Suspending","startTime":"2025-03-05T22:40:41Z","succeeded":0,"failed":0,"rayClusterStatus":{"desiredCPU":"0","desiredMemory":"0","desiredGPU":"0","desiredTPU":"0","head":{}}}}
2025-03-05T22:40:41.747373524Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.747Z","logger":"controllers.RayJob","msg":"updateRayJobStatus","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"9ea0d50f-11cb-4f19-b0f9-67d9fae463b5","old JobStatus":"","new JobStatus":"","old JobDeploymentStatus":"Initializing","new JobDeploymentStatus":"Suspending"}
2025-03-05T22:40:41.816458069Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.816Z","logger":"controllers.RayJob","msg":"RayJob","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"1b4aac45-a7ca-4c4e-937d-db5893fa9ce8","name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj","JobStatus":"","JobDeploymentStatus":"Initializing","SubmissionMode":"K8sJobMode"}
2025-03-05T22:40:41.81648789Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.816Z","logger":"controllers.RayJob","msg":"Try to transition the status from `Initializing` to `Suspending`","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"1b4aac45-a7ca-4c4e-937d-db5893fa9ce8","RayJob":"ranks-ray"}
2025-03-05T22:40:41.81649374Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.816Z","logger":"controllers.RayJob","msg":"updateRayJobStatus","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"1b4aac45-a7ca-4c4e-937d-db5893fa9ce8","oldRayJobStatus":{"jobId":"ranks-ray-cmmqx","rayClusterName":"ranks-ray-raycluster-sr57x","jobDeploymentStatus":"Initializing","startTime":"2025-03-05T22:40:41Z","succeeded":0,"failed":0,"rayClusterStatus":{"desiredCPU":"0","desiredMemory":"0","desiredGPU":"0","desiredTPU":"0","head":{}}},"newRayJobStatus":{"jobId":"ranks-ray-cmmqx","rayClusterName":"ranks-ray-raycluster-sr57x","jobDeploymentStatus":"Suspending","startTime":"2025-03-05T22:40:41Z","succeeded":0,"failed":0,"rayClusterStatus":{"desiredCPU":"0","desiredMemory":"0","desiredGPU":"0","desiredTPU":"0","head":{}}}}
2025-03-05T22:40:41.81649839Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.816Z","logger":"controllers.RayJob","msg":"updateRayJobStatus","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"1b4aac45-a7ca-4c4e-937d-db5893fa9ce8","old JobStatus":"","new JobStatus":"","old JobDeploymentStatus":"Initializing","new JobDeploymentStatus":"Suspending"}
2025-03-05T22:40:41.82394229Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.823Z","logger":"controllers.RayJob","msg":"Failed to update RayJob status","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"1b4aac45-a7ca-4c4e-937d-db5893fa9ce8","error":"Operation cannot be fulfilled on rayjobs.ray.io \"ranks-ray\": the object has been modified; please apply your changes to the latest version and try again"}
2025-03-05T22:40:41.82396275Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.823Z","logger":"controllers.RayJob","msg":"Warning: Reconciler returned both a non-zero result and a non-nil error. The result will always be ignored if the error is non-nil and the non-nil error causes reqeueuing with exponential backoff. For more details, see: https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/reconcile#Reconciler","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"1b4aac45-a7ca-4c4e-937d-db5893fa9ce8"}
2025-03-05T22:40:41.823982881Z stderr F {"level":"error","ts":"2025-03-05T22:40:41.823Z","logger":"controllers.RayJob","msg":"Reconciler error","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"1b4aac45-a7ca-4c4e-937d-db5893fa9ce8","error":"Operation cannot be fulfilled on rayjobs.ray.io \"ranks-ray\": the object has been modified; please apply your changes to the latest version and try again","stacktrace":"sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).reconcileHandler\n\t/home/runner/go/pkg/mod/sigs.k8s.io/controller-runtime@v0.17.5/pkg/internal/controller/controller.go:329\nsigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).processNextWorkItem\n\t/home/runner/go/pkg/mod/sigs.k8s.io/controller-runtime@v0.17.5/pkg/internal/controller/controller.go:266\nsigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).Start.func2.2\n\t/home/runner/go/pkg/mod/sigs.k8s.io/controller-runtime@v0.17.5/pkg/internal/controller/controller.go:227"}
2025-03-05T22:40:41.824197244Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.824Z","logger":"controllers.RayJob","msg":"RayJob","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"f07521e0-7c67-4257-b8d3-8dc5f4dea4f5","name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj","JobStatus":"","JobDeploymentStatus":"Suspending","SubmissionMode":"K8sJobMode"}
2025-03-05T22:40:41.824208124Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.824Z","logger":"controllers.RayJob","msg":"The associated RayCluster for RayJob has been already deleted and it can not be found","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"f07521e0-7c67-4257-b8d3-8dc5f4dea4f5","RayCluster":{"name":"ranks-ray-raycluster-sr57x","namespace":"e2e-tas-rayjob-lgmbj"},"RayJob":"ranks-ray"}
2025-03-05T22:40:41.824212334Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.824Z","logger":"controllers.RayJob","msg":"deleteClusterResources","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"f07521e0-7c67-4257-b8d3-8dc5f4dea4f5","isClusterDeleted":true}
2025-03-05T22:40:41.824235294Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.824Z","logger":"controllers.RayJob","msg":"The submitter Kubernetes Job has been already deleted","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"f07521e0-7c67-4257-b8d3-8dc5f4dea4f5","RayJob":"ranks-ray","Kubernetes Job":""}
2025-03-05T22:40:41.824245074Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.824Z","logger":"controllers.RayJob","msg":"deleteSubmitterJob","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"f07521e0-7c67-4257-b8d3-8dc5f4dea4f5","isJobDeleted":true}
2025-03-05T22:40:41.824268085Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.824Z","logger":"controllers.RayJob","msg":"updateRayJobStatus","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"f07521e0-7c67-4257-b8d3-8dc5f4dea4f5","oldRayJobStatus":{"jobId":"ranks-ray-cmmqx","rayClusterName":"ranks-ray-raycluster-sr57x","jobDeploymentStatus":"Suspending","startTime":"2025-03-05T22:40:41Z","succeeded":0,"failed":0,"rayClusterStatus":{"desiredCPU":"0","desiredMemory":"0","desiredGPU":"0","desiredTPU":"0","head":{}}},"newRayJobStatus":{"jobDeploymentStatus":"Suspended","startTime":"2025-03-05T22:40:41Z","succeeded":0,"failed":0,"rayClusterStatus":{"desiredCPU":"0","desiredMemory":"0","desiredGPU":"0","desiredTPU":"0","head":{}}}}
2025-03-05T22:40:41.824272795Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.824Z","logger":"controllers.RayJob","msg":"updateRayJobStatus","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"f07521e0-7c67-4257-b8d3-8dc5f4dea4f5","old JobStatus":"","new JobStatus":"","old JobDeploymentStatus":"Suspending","new JobDeploymentStatus":"Suspended"}
2025-03-05T22:40:41.915895512Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.915Z","logger":"controllers.RayJob","msg":"RayJob","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"e3781e9d-5a57-4d4c-b995-ee8a346246e1","name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj","JobStatus":"","JobDeploymentStatus":"Suspended","SubmissionMode":"K8sJobMode"}
2025-03-05T22:40:41.915933503Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.915Z","logger":"controllers.RayJob","msg":"The status is 'Suspended', but the suspend flag is false. Transition the status to 'New'.","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"e3781e9d-5a57-4d4c-b995-ee8a346246e1"}
2025-03-05T22:40:41.915943313Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.915Z","logger":"controllers.RayJob","msg":"updateRayJobStatus","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"e3781e9d-5a57-4d4c-b995-ee8a346246e1","oldRayJobStatus":{"jobDeploymentStatus":"Suspended","startTime":"2025-03-05T22:40:41Z","succeeded":0,"failed":0,"rayClusterStatus":{"desiredCPU":"0","desiredMemory":"0","desiredGPU":"0","desiredTPU":"0","head":{}}},"newRayJobStatus":{"startTime":"2025-03-05T22:40:41Z","succeeded":0,"failed":0,"rayClusterStatus":{"desiredCPU":"0","desiredMemory":"0","desiredGPU":"0","desiredTPU":"0","head":{}}}}
2025-03-05T22:40:41.915947083Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.915Z","logger":"controllers.RayJob","msg":"updateRayJobStatus","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"e3781e9d-5a57-4d4c-b995-ee8a346246e1","old JobStatus":"","new JobStatus":"","old JobDeploymentStatus":"Suspended","new JobDeploymentStatus":""}
2025-03-05T22:40:41.928126647Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.927Z","logger":"controllers.RayJob","msg":"RayJob","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"d716e4ba-f93f-427b-935c-dfae9eec7d52","name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj","JobStatus":"","JobDeploymentStatus":"","SubmissionMode":"K8sJobMode"}
2025-03-05T22:40:41.928151017Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.927Z","logger":"controllers.RayJob","msg":"JobDeploymentStatusNew","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"d716e4ba-f93f-427b-935c-dfae9eec7d52","RayJob":"ranks-ray"}
2025-03-05T22:40:41.928156777Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.927Z","logger":"controllers.RayJob","msg":"initRayJobStatusIfNeed","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"d716e4ba-f93f-427b-935c-dfae9eec7d52","shouldUpdateStatus":true,"RayJob":"ranks-ray","jobId":"","rayClusterName":"","jobStatus":""}
2025-03-05T22:40:41.928162858Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.927Z","logger":"controllers.RayJob","msg":"updateRayJobStatus","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"d716e4ba-f93f-427b-935c-dfae9eec7d52","oldRayJobStatus":{"startTime":"2025-03-05T22:40:41Z","succeeded":0,"failed":0,"rayClusterStatus":{"desiredCPU":"0","desiredMemory":"0","desiredGPU":"0","desiredTPU":"0","head":{}}},"newRayJobStatus":{"jobId":"ranks-ray-vzvd2","rayClusterName":"ranks-ray-raycluster-gpzrs","jobDeploymentStatus":"Initializing","startTime":"2025-03-05T22:40:41Z","succeeded":0,"failed":0,"rayClusterStatus":{"desiredCPU":"0","desiredMemory":"0","desiredGPU":"0","desiredTPU":"0","head":{}}}}
2025-03-05T22:40:41.928183918Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.928Z","logger":"controllers.RayJob","msg":"updateRayJobStatus","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"d716e4ba-f93f-427b-935c-dfae9eec7d52","old JobStatus":"","new JobStatus":"","old JobDeploymentStatus":"","new JobDeploymentStatus":"Initializing"}
2025-03-05T22:40:41.939842544Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.939Z","logger":"controllers.RayJob","msg":"RayJob","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"ace14a20-d46a-48ce-b78b-e792f4a93afc","name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj","JobStatus":"","JobDeploymentStatus":"Initializing","SubmissionMode":"K8sJobMode"}
2025-03-05T22:40:41.939879045Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.939Z","logger":"controllers.RayJob","msg":"try to find existing RayCluster instance","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"ace14a20-d46a-48ce-b78b-e792f4a93afc","name":"ranks-ray-raycluster-gpzrs"}
2025-03-05T22:40:41.939882965Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.939Z","logger":"controllers.RayJob","msg":"RayCluster not found","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"ace14a20-d46a-48ce-b78b-e792f4a93afc","RayJob":"ranks-ray","RayCluster":{"name":"ranks-ray-raycluster-gpzrs","namespace":"e2e-tas-rayjob-lgmbj"}}
2025-03-05T22:40:41.939886725Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.939Z","logger":"controllers.RayJob","msg":"RayCluster not found, creating RayCluster!","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"ace14a20-d46a-48ce-b78b-e792f4a93afc","RayCluster":{"name":"ranks-ray-raycluster-gpzrs","namespace":"e2e-tas-rayjob-lgmbj"}}
2025-03-05T22:40:41.959965164Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.959Z","logger":"controllers.RayJob","msg":"Found the associated RayCluster for RayJob","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"ace14a20-d46a-48ce-b78b-e792f4a93afc","RayJob":"ranks-ray","RayCluster":{"name":"ranks-ray-raycluster-gpzrs","namespace":"e2e-tas-rayjob-lgmbj"}}
2025-03-05T22:40:41.960283748Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.960Z","logger":"controllers.RayJob","msg":"Wait for the RayCluster.Status.State to be ready before submitting the job.","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"ace14a20-d46a-48ce-b78b-e792f4a93afc","RayCluster":"ranks-ray-raycluster-gpzrs","State":""}
2025-03-05T22:40:41.96039025Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.960Z","logger":"controllers.RayCluster","msg":"Reconciling Ingress","RayCluster":{"name":"ranks-ray-raycluster-gpzrs","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"40c15835-bf09-4127-bb0b-cbc807ce37c2"}
2025-03-05T22:40:41.960543902Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.960Z","logger":"controllers.RayJob","msg":"RayJob","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"efb844e5-185c-4b5a-9702-eaf3d34be173","name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj","JobStatus":"","JobDeploymentStatus":"Initializing","SubmissionMode":"K8sJobMode"}
2025-03-05T22:40:41.960555872Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.960Z","logger":"controllers.RayJob","msg":"try to find existing RayCluster instance","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"efb844e5-185c-4b5a-9702-eaf3d34be173","name":"ranks-ray-raycluster-gpzrs"}
2025-03-05T22:40:41.960561152Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.960Z","logger":"controllers.RayJob","msg":"Found the associated RayCluster for RayJob","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"efb844e5-185c-4b5a-9702-eaf3d34be173","RayJob":"ranks-ray","RayCluster":{"name":"ranks-ray-raycluster-gpzrs","namespace":"e2e-tas-rayjob-lgmbj"}}
2025-03-05T22:40:41.960836436Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.960Z","logger":"controllers.RayJob","msg":"Wait for the RayCluster.Status.State to be ready before submitting the job.","RayJob":{"name":"ranks-ray","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"efb844e5-185c-4b5a-9702-eaf3d34be173","RayCluster":"ranks-ray-raycluster-gpzrs","State":""}
2025-03-05T22:40:41.964783758Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.964Z","logger":"controllers.RayCluster","msg":"Created service for RayCluster","RayCluster":{"name":"ranks-ray-raycluster-gpzrs","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"40c15835-bf09-4127-bb0b-cbc807ce37c2","name":"ranks-ray-raycluster-gpzrs-head-svc"}
2025-03-05T22:40:41.964833089Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.964Z","logger":"controllers.RayCluster","msg":"reconcilePods","RayCluster":{"name":"ranks-ray-raycluster-gpzrs","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"40c15835-bf09-4127-bb0b-cbc807ce37c2","Found 0 head Pods; creating a head Pod for the RayCluster.":"ranks-ray-raycluster-gpzrs"}
2025-03-05T22:40:41.964956361Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.964Z","logger":"controllers.RayCluster","msg":"head pod labels","RayCluster":{"name":"ranks-ray-raycluster-gpzrs","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"40c15835-bf09-4127-bb0b-cbc807ce37c2","labels":{"app.kubernetes.io/created-by":"kuberay-operator","app.kubernetes.io/name":"kuberay","kueue.x-k8s.io/podset":"head","kueue.x-k8s.io/tas":"true","ray.io/cluster":"ranks-ray-raycluster-gpzrs","ray.io/group":"headgroup","ray.io/identifier":"ranks-ray-raycluster-gpzrs-head","ray.io/is-ray-node":"yes","ray.io/node-type":"head"}}
2025-03-05T22:40:41.964969311Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.964Z","logger":"controllers.RayCluster","msg":"generateRayStartCommand","RayCluster":{"name":"ranks-ray-raycluster-gpzrs","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"40c15835-bf09-4127-bb0b-cbc807ce37c2","nodeType":"head","rayStartParams":{"block":"true","dashboard-agent-listen-port":"52365","dashboard-host":"0.0.0.0","metrics-export-port":"8080"},"Ray container resource":{"limits":{"cpu":"100m"},"requests":{"cpu":"100m"}}}
2025-03-05T22:40:41.964974551Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.964Z","logger":"controllers.RayCluster","msg":"generateRayStartCommand","RayCluster":{"name":"ranks-ray-raycluster-gpzrs","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"40c15835-bf09-4127-bb0b-cbc807ce37c2","rayStartCmd":"ray start --head  --num-cpus=1  --dashboard-host=0.0.0.0  --metrics-export-port=8080  --block  --dashboard-agent-listen-port=52365 "}
2025-03-05T22:40:41.964990721Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.964Z","logger":"controllers.RayCluster","msg":"BuildPod","RayCluster":{"name":"ranks-ray-raycluster-gpzrs","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"40c15835-bf09-4127-bb0b-cbc807ce37c2","rayNodeType":"head","generatedCmd":"ulimit -n 65536; ray start --head  --num-cpus=1  --dashboard-host=0.0.0.0  --metrics-export-port=8080  --block  --dashboard-agent-listen-port=52365 "}
2025-03-05T22:40:41.965002051Z stderr F {"level":"info","ts":"2025-03-05T22:40:41.964Z","logger":"controllers.RayCluster","msg":"Probes injection feature flag","RayCluster":{"name":"ranks-ray-raycluster-gpzrs","namespace":"e2e-tas-rayjob-lgmbj"},"reconcileID":"40c15835-bf09-4127-bb0b-cbc807ce37c2","enabled":true}
```

So some interesting logs are **The associated RayCluster for RayJob has been already deleted and it can not be found**, or **The submitter Kubernetes Job has been already deleted** at `2025-03-05T22:40:41.824` even though the kube-apiserver logs don't show any DELETE requests to the Ray APIs in this perdiod. Maybe there is some racing with the creation events not being delivered on time?

So, I expect this is actually a bug / flake in KubeRay 1.2.2. 

cc @andrewsykim have you seen something like this? If so, is this fixed in 1.3.x?@mimowo: cc @tenzen-y @tenzen-y: Thank you for investigating this one. If this actually KubeRay side bug, we can skip this case until this fixes are shipped from KubeRay.
@mimowo: > For this one I think we might want to change the approach.

I synced with @andrewsykim who says the issue looks "vaguely familiar", and there is some chance it is already fixed in 1.3. So instead of refactoring or relaxing tests we can just wait a bit. 

cc @mszadkow @tenzen-y: > > For this one I think we might want to change the approach.
> 
> I synced with [@andrewsykim](https://github.com/andrewsykim) who says the issue looks "vaguely familiar", and there is some chance it is already fixed in 1.3. So instead of refactoring or relaxing tests we can just wait a bit.
> 
> cc [@mszadkow](https://github.com/mszadkow)

Thank you for letting me know.

Solution patch:
diff --git a/Makefile-test.mk b/Makefile-test.mk
index 77679b5a1..8d725b5b9 100644
--- a/Makefile-test.mk
+++ b/Makefile-test.mk
@@ -34,6 +34,8 @@ LD_FLAGS += -X '$(version_pkg).GitCommit=$(shell git rev-parse HEAD)'
 # ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary.
 ENVTEST_K8S_VERSION ?= 1.32
 
+TEST_LOG_LEVEL ?= -3
+
 # Number of processes to use during integration tests to run specs within a
 # suite in parallel. Suites still run sequentially. User may set this value to 1
 # to run without parallelism.
@@ -88,7 +90,7 @@ test-integration: gomod-download envtest ginkgo dep-crds kueuectl ginkgo-top ##
 	PROJECT_DIR=$(PROJECT_DIR)/ \
 	KUEUE_BIN=$(PROJECT_DIR)/bin \
 	ENVTEST_K8S_VERSION=$(ENVTEST_K8S_VERSION) \
-	API_LOG_LEVEL=$(INTEGRATION_API_LOG_LEVEL) \
+	TEST_LOG_LEVEL=$(TEST_LOG_LEVEL) API_LOG_LEVEL=$(INTEGRATION_API_LOG_LEVEL) \
 	$(GINKGO) $(INTEGRATION_FILTERS) $(GINKGO_ARGS) $(GOFLAGS) -procs=$(INTEGRATION_NPROCS) --race --junit-report=junit.xml --json-report=integration.json --output-dir=$(ARTIFACTS) -v $(INTEGRATION_TARGET)
 	$(PROJECT_DIR)/bin/ginkgo-top -i $(ARTIFACTS)/integration.json > $(ARTIFACTS)/integration-top.yaml
 
@@ -98,7 +100,7 @@ test-multikueue-integration: gomod-download envtest ginkgo dep-crds kueuectl gin
 	PROJECT_DIR=$(PROJECT_DIR)/ \
 	KUEUE_BIN=$(PROJECT_DIR)/bin \
 	ENVTEST_K8S_VERSION=$(ENVTEST_K8S_VERSION) \
-	API_LOG_LEVEL=$(INTEGRATION_API_LOG_LEVEL) \
+	TEST_LOG_LEVEL=$(TEST_LOG_LEVEL) API_LOG_LEVEL=$(INTEGRATION_API_LOG_LEVEL) \
 	$(GINKGO) $(INTEGRATION_FILTERS) $(GINKGO_ARGS) $(GOFLAGS) -procs=$(INTEGRATION_NPROCS_MULTIKUEUE) --race --junit-report=multikueue-junit.xml --json-report=multikueue-integration.json --output-dir=$(ARTIFACTS) -v $(INTEGRATION_TARGET_MULTIKUEUE)
 	$(PROJECT_DIR)/bin/ginkgo-top -i $(ARTIFACTS)/multikueue-integration.json > $(ARTIFACTS)/multikueue-integration-top.yaml
 
@@ -132,6 +134,7 @@ run-test-e2e-singlecluster-%: FORCE
 		JOBSET_VERSION=$(JOBSET_VERSION) \
 		LEADERWORKERSET_VERSION=$(LEADERWORKERSET_VERSION) \
 		KIND_CLUSTER_FILE="kind-cluster.yaml" E2E_TARGET_FOLDER="singlecluster" \
+		TEST_LOG_LEVEL=$(TEST_LOG_LEVEL) \
 		./hack/e2e-test.sh
 	$(PROJECT_DIR)/bin/ginkgo-top -i $(ARTIFACTS)/$@/e2e.json > $(ARTIFACTS)/$@/e2e-top.yaml
 
@@ -143,6 +146,7 @@ run-test-multikueue-e2e-%: FORCE
 		APPWRAPPER_VERSION=$(APPWRAPPER_VERSION) \
 		JOBSET_VERSION=$(JOBSET_VERSION) KUBEFLOW_VERSION=$(KUBEFLOW_VERSION) \
 		KUBEFLOW_MPI_VERSION=$(KUBEFLOW_MPI_VERSION) KUBERAY_VERSION=$(KUBERAY_VERSION) \
+		TEST_LOG_LEVEL=$(TEST_LOG_LEVEL) \
 		./hack/multikueue-e2e-test.sh
 	$(PROJECT_DIR)/bin/ginkgo-top -i $(ARTIFACTS)/$@/e2e.json > $(ARTIFACTS)/$@/e2e-top.yaml
 
@@ -156,6 +160,7 @@ run-test-tas-e2e-%: FORCE
 		LEADERWORKERSET_VERSION=$(LEADERWORKERSET_VERSION) \
 		KUBERAY_VERSION=$(KUBERAY_VERSION) \
 		KIND_CLUSTER_FILE="tas-kind-cluster.yaml" E2E_TARGET_FOLDER="tas" \
+		TEST_LOG_LEVEL=$(TEST_LOG_LEVEL) \
 		./hack/e2e-test.sh
 	$(PROJECT_DIR)/bin/ginkgo-top -i $(ARTIFACTS)/$@/e2e.json > $(ARTIFACTS)/$@/e2e-top.yaml
 
@@ -166,6 +171,7 @@ run-test-e2e-customconfigs-%: FORCE
 		ARTIFACTS="$(ARTIFACTS)/$@" IMAGE_TAG=$(IMAGE_TAG) GINKGO_ARGS="$(GINKGO_ARGS)" \
 		KIND_CLUSTER_FILE="kind-cluster.yaml" E2E_TARGET_FOLDER="customconfigs" \
 		JOBSET_VERSION=$(JOBSET_VERSION) APPWRAPPER_VERSION=$(APPWRAPPER_VERSION) \
+		TEST_LOG_LEVEL=$(TEST_LOG_LEVEL) \
 		./hack/e2e-test.sh
 	$(PROJECT_DIR)/bin/ginkgo-top -i $(ARTIFACTS)/$@/e2e.json > $(ARTIFACTS)/$@/e2e-top.yaml
 
diff --git a/apis/config/v1beta1/configuration_types.go b/apis/config/v1beta1/configuration_types.go
index 9acb2c619..d2484a6d4 100644
--- a/apis/config/v1beta1/configuration_types.go
+++ b/apis/config/v1beta1/configuration_types.go
@@ -318,9 +318,16 @@ const (
 )
 
 type InternalCertManagement struct {
-	// Enable controls whether to enable internal cert management or not.
-	// Defaults to true. If you want to use a third-party management, e.g. cert-manager,
-	// set it to false. See the user guide for more information.
+	// Enable controls the use of internal cert management for the webhook
+	// and metrics endpoints.
+	// When enabled Kueue is using libraries to generate and
+	// self-sign the certificates.
+	// When disabled, you need to provide the certificates for
+	// the webhooks and metrics through a third party certificate
+	// This secret is mounted to the kueue controller manager pod. The mount
+	// path for webhooks is /tmp/k8s-webhook-server/serving-certs, whereas for
+	// metrics endpoint the expected path is `/etc/kueue/metrics/certs`.
+	// The keys and certs are named tls.key and tls.crt.
 	Enable *bool `json:"enable,omitempty"`
 
 	// WebhookServiceName is the name of the Service used as part of the DNSName.
diff --git a/apis/kueue/v1alpha1/tas_types.go b/apis/kueue/v1alpha1/tas_types.go
index 5538b2d61..84ba98f03 100644
--- a/apis/kueue/v1alpha1/tas_types.go
+++ b/apis/kueue/v1alpha1/tas_types.go
@@ -38,6 +38,14 @@ const (
 	// among multiple topology domains.
 	PodSetPreferredTopologyAnnotation = "kueue.x-k8s.io/podset-preferred-topology"
 
+	// PodSetUnconstrainedTopologyAnnotation indicates that a PodSet does not have any topology requirements.
+	// Kueue admits the PodSet if there's enough free capacity available.
+	// Recommended for PodSets that don't need low-latency or high-throughput pod-to-pod communication,
+	// but want to leverage TAS capabilities improve accuracy of admitting jobs
+	//
+	// +kubebuilder:validation:Type=boolean
+	PodSetUnconstrainedTopologyAnnotation = "kueue.x-k8s.io/podset-unconstrained-topology"
+
 	// TopologySchedulingGate is used to delay scheduling of a Pod until the
 	// nodeSelectors corresponding to the assigned topology domain are injected
 	// into the Pod. For the Pod-based integrations the gate is added in webhook
diff --git a/apis/kueue/v1beta1/workload_types.go b/apis/kueue/v1beta1/workload_types.go
index be31e10ce..db8a7c2b1 100644
--- a/apis/kueue/v1beta1/workload_types.go
+++ b/apis/kueue/v1beta1/workload_types.go
@@ -104,6 +104,14 @@ type PodSetTopologyRequest struct {
 	// +optional
 	Preferred *string `json:"preferred,omitempty"`
 
+	// unconstrained indicates that Kueue has the freedom to schedule the PodSet within
+	// the entire available capacity, without constraints on the compactness of the placement.
+	// This is indicated by the `kueue.x-k8s.io/podset-unconstrained-topology` PodSet annotation.
+	//
+	// +optional
+	// +kubebuilder:validation:Type=boolean
+	Unconstrained *bool `json:"unconstrained,omitempty"`
+
 	// PodIndexLabel indicates the name of the label indexing the pods.
 	// For example, in the context of
 	// - kubernetes job this is: kubernetes.io/job-completion-index
diff --git a/apis/kueue/v1beta1/zz_generated.deepcopy.go b/apis/kueue/v1beta1/zz_generated.deepcopy.go
index 19af8c5e5..b6ab50c9f 100644
--- a/apis/kueue/v1beta1/zz_generated.deepcopy.go
+++ b/apis/kueue/v1beta1/zz_generated.deepcopy.go
@@ -1055,6 +1055,11 @@ func (in *PodSetTopologyRequest) DeepCopyInto(out *PodSetTopologyRequest) {
 		*out = new(string)
 		**out = **in
 	}
+	if in.Unconstrained != nil {
+		in, out := &in.Unconstrained, &out.Unconstrained
+		*out = new(bool)
+		**out = **in
+	}
 	if in.PodIndexLabel != nil {
 		in, out := &in.PodIndexLabel, &out.PodIndexLabel
 		*out = new(string)
diff --git a/charts/kueue/OWNERS b/charts/kueue/OWNERS
new file mode 100644
index 000000000..ef7abba9d
--- /dev/null
+++ b/charts/kueue/OWNERS
@@ -0,0 +1,5 @@
+# See the OWNERS docs at https://go.k8s.io/owners
+
+reviewers:
+- kannon92
+
diff --git a/charts/kueue/templates/certmanager/certificatemetrics.yaml b/charts/kueue/templates/certmanager/certificatemetrics.yaml
new file mode 100644
index 000000000..4c5cf15fb
--- /dev/null
+++ b/charts/kueue/templates/certmanager/certificatemetrics.yaml
@@ -0,0 +1,17 @@
+{{- if .Values.enableCertManager }}
+apiVersion: cert-manager.io/v1
+kind: Certificate
+metadata:
+  name: {{ include "kueue.fullname" . }}-metrics-cert
+  namespace: '{{ .Release.Namespace }}'
+  labels:
+  {{- include "kueue.labels" . | nindent 4 }}
+spec:
+  dnsNames:
+  - '{{ include "kueue.fullname" . }}-controller-manager-metrics-service.{{ .Release.Namespace }}.svc'
+  - '{{ include "kueue.fullname" . }}-controller-manager-metrics-service.{{ .Release.Namespace }}.svc.{{ .Values.kubernetesClusterDomain }}'
+  issuerRef:
+    kind: Issuer
+    name: {{ include "kueue.fullname" . }}-selfsigned-issuer
+  secretName: {{ include "kueue.fullname" . }}-metrics-server-cert
+{{- end }}
\ No newline at end of file
diff --git a/charts/kueue/templates/crd/kueue.x-k8s.io_workloads.yaml b/charts/kueue/templates/crd/kueue.x-k8s.io_workloads.yaml
index 03a39b556..5767c72f3 100644
--- a/charts/kueue/templates/crd/kueue.x-k8s.io_workloads.yaml
+++ b/charts/kueue/templates/crd/kueue.x-k8s.io_workloads.yaml
@@ -8329,6 +8329,12 @@ spec:
                             SubGroupIndexLabel indicates the name of the label indexing the instances of replicated Jobs (groups)
                             within a PodSet. For example, in the context of JobSet this is jobset.sigs.k8s.io/job-index.
                           type: string
+                        unconstrained:
+                          description: |-
+                            unconstrained indicates that Kueue has the freedom to schedule the PodSet within
+                            the entire available capacity, without constraints on the compactness of the placement.
+                            This is indicated by the `kueue.x-k8s.io/podset-unconstrained-topology` PodSet annotation.
+                          type: boolean
                       type: object
                   required:
                   - count
diff --git a/charts/kueue/templates/manager/manager.yaml b/charts/kueue/templates/manager/manager.yaml
index b1be101ff..06dff5922 100644
--- a/charts/kueue/templates/manager/manager.yaml
+++ b/charts/kueue/templates/manager/manager.yaml
@@ -70,6 +70,11 @@ spec:
         - mountPath: /controller_manager_config.yaml
           name: manager-config
           subPath: controller_manager_config.yaml
+        {{- if .Values.enableCertManager }}
+        - mountPath: /etc/kueue/metrics/certs
+          name: metrics-certs
+          readOnly: true
+        {{- end }}
       securityContext:
         {{- toYaml .Values.controllerManager.manager.podSecurityContext | nindent 8 }}
       serviceAccountName: {{ include "kueue.fullname" . }}-controller-manager
@@ -87,6 +92,19 @@ spec:
         secret:
           defaultMode: 420
           secretName: {{ include "kueue.fullname" . }}-webhook-server-cert
-      - configMap:
+      - name: manager-config
+        configMap:
           name: {{ include "kueue.fullname" . }}-manager-config
-        name: manager-config
+      {{- if .Values.enableCertManager }}
+      - name: metrics-certs
+        secret:
+          secretName: {{ include "kueue.fullname" . }}-metrics-server-cert
+          optional: false
+          items:
+          - key: ca.crt
+            path: ca.crt
+          - key: tls.crt
+            path: tls.crt
+          - key: tls.key
+            path: tls.key
+      {{- end }}
diff --git a/charts/kueue/templates/prometheus/monitor.yaml b/charts/kueue/templates/prometheus/monitor.yaml
index 6798ae63a..7ce986f29 100644
--- a/charts/kueue/templates/prometheus/monitor.yaml
+++ b/charts/kueue/templates/prometheus/monitor.yaml
@@ -12,8 +12,7 @@ spec:
     path: /metrics
     port: https
     scheme: https
-    tlsConfig:
-      insecureSkipVerify: true
+    tlsConfig: {{- toYaml .Values.metrics.serviceMonitor.tlsConfig | nindent 6 }}
   selector:
     matchLabels:
     {{- include "kueue.labels" . | nindent 6 }}
diff --git a/charts/kueue/values.yaml b/charts/kueue/values.yaml
index 06360e595..18518abfc 100644
--- a/charts/kueue/values.yaml
+++ b/charts/kueue/values.yaml
@@ -156,3 +156,6 @@ enableKueueViz: false
 
 metrics:
   prometheusNamespace: monitoring
+  serviceMonitor:
+    tlsConfig:
+      insecureSkipVerify: true
diff --git a/client-go/applyconfiguration/kueue/v1beta1/podsettopologyrequest.go b/client-go/applyconfiguration/kueue/v1beta1/podsettopologyrequest.go
index 906eef5ad..3756f7181 100644
--- a/client-go/applyconfiguration/kueue/v1beta1/podsettopologyrequest.go
+++ b/client-go/applyconfiguration/kueue/v1beta1/podsettopologyrequest.go
@@ -22,6 +22,7 @@ package v1beta1
 type PodSetTopologyRequestApplyConfiguration struct {
 	Required           *string `json:"required,omitempty"`
 	Preferred          *string `json:"preferred,omitempty"`
+	Unconstrained      *bool   `json:"unconstrained,omitempty"`
 	PodIndexLabel      *string `json:"podIndexLabel,omitempty"`
 	SubGroupIndexLabel *string `json:"subGroupIndexLabel,omitempty"`
 	SubGroupCount      *int32  `json:"subGroupCount,omitempty"`
@@ -49,6 +50,14 @@ func (b *PodSetTopologyRequestApplyConfiguration) WithPreferred(value string) *P
 	return b
 }
 
+// WithUnconstrained sets the Unconstrained field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the Unconstrained field is set to the value of the last call.
+func (b *PodSetTopologyRequestApplyConfiguration) WithUnconstrained(value bool) *PodSetTopologyRequestApplyConfiguration {
+	b.Unconstrained = &value
+	return b
+}
+
 // WithPodIndexLabel sets the PodIndexLabel field in the declarative configuration to the given value
 // and returns the receiver, so that objects can be built by chaining "With" function invocations.
 // If called multiple times, the PodIndexLabel field is set to the value of the last call.
diff --git a/cmd/experimental/kueue-viz/frontend/.dockerignore b/cmd/experimental/kueue-viz/frontend/.dockerignore
new file mode 100644
index 000000000..a031a9e8c
--- /dev/null
+++ b/cmd/experimental/kueue-viz/frontend/.dockerignore
@@ -0,0 +1,7 @@
+.gitignore
+.git
+.env*
+*.log
+node_modules
+build
+README.md
diff --git a/cmd/experimental/kueue-viz/frontend/.env b/cmd/experimental/kueue-viz/frontend/.env
index c2f275d40..84e794bfc 100644
--- a/cmd/experimental/kueue-viz/frontend/.env
+++ b/cmd/experimental/kueue-viz/frontend/.env
@@ -1 +1,2 @@
+VITE_WEBSOCKET_URL=ws://localhost:8080
 REACT_APP_WEBSOCKET_URL=ws://localhost:8080
diff --git a/cmd/experimental/kueue-viz/frontend/Dockerfile b/cmd/experimental/kueue-viz/frontend/Dockerfile
index 4319f5e70..e9843148a 100644
--- a/cmd/experimental/kueue-viz/frontend/Dockerfile
+++ b/cmd/experimental/kueue-viz/frontend/Dockerfile
@@ -1,19 +1,36 @@
-#Build the React app
-FROM node:23 AS build
+# Build stage
+FROM node:23 AS builder
 
-ENV NPM_CONFIG_CACHE=/tmp/.npm-cache
+# Set working directory
 WORKDIR /app
+
+# Copy package files
 COPY package*.json ./
+
+# Install ALL dependencies (including dev dependencies needed for build)
 RUN npm install
+
+# Copy source files
 COPY . .
 
-# Build the production-ready static files
+# Build the app
 RUN npm run build
-RUN mkdir -p build && touch build/env.js && chmod ugo+rw -R build/ $NPM_CONFIG_CACHE
-EXPOSE 8080
 
-# Use react-inject-env to be able to inject env vars at runtime
-ENTRYPOINT npx react-inject-env set && npx http-server build
+# Runtime stage
+FROM node:23 AS runtime
 
+WORKDIR /app
+
+# Install serve for production static file serving
+RUN npm install -g serve
+
+# Copy only the built files from builder
+COPY --from=builder /app/build ./build
+COPY start.sh /app/start.sh
+RUN chmod +x /app/start.sh
+
+EXPOSE 8080
 
+# Use the start script
+ENTRYPOINT ["/app/start.sh"]
 
diff --git a/cmd/experimental/kueue-viz/frontend/index.html b/cmd/experimental/kueue-viz/frontend/index.html
new file mode 100644
index 000000000..c01300ff1
--- /dev/null
+++ b/cmd/experimental/kueue-viz/frontend/index.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <script src='/env.js'></script>
+    <meta charset="utf-8" />
+    <link rel="icon" href="/favicon.ico" />
+    <meta name="viewport" content="width=device-width, initial-scale=1" />
+    <meta name="theme-color" content="#000000" />
+    <meta
+      name="description"
+      content="Kueue Visualization Dashboard"
+    />
+    <title>Kueue Dashboard</title>
+  </head>
+  <body>
+    <noscript>You need to enable JavaScript to run this app.</noscript>
+    <div id="root"></div>
+    <script type="module" src="/src/index.jsx"></script>
+  </body>
+</html> 
\ 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 172e22de2..4009d56df 100644
--- a/cmd/experimental/kueue-viz/frontend/package.json
+++ b/cmd/experimental/kueue-viz/frontend/package.json
@@ -3,26 +3,30 @@
   "version": "1.0.0",
   "private": true,
   "description": "Frontend dashboard for visualizing Kueue status",
-  "main": "src/index.js",
+  "main": "src/index.jsx",
+  "type": "module",
   "scripts": {
-    "start": "SKIP_PREFLIGHT_CHECK=true react-scripts start",
-    "build": "SKIP_PREFLIGHT_CHECK=true react-scripts build"
+    "start": "vite",
+    "build": "vite build",
+    "preview": "vite preview",
+    "check-unused": "depcheck"
   },
   "dependencies": {
-    "@emotion/react": "^11.0.0",
-    "@emotion/styled": "^11.0.0",
-    "@mui/icons-material": "^6.4.6",
-    "@mui/material": "^6.4.6",
-    "axios": "^1.7.9",
+    "@emotion/react": "^11.14.0",
+    "@emotion/styled": "^11.14.0",
+    "@mui/icons-material": "^6.4.7",
+    "@mui/material": "^6.4.7",
+    "axios": "^1.8.3",
     "react": "^19.0.0",
     "react-dom": "^19.0.0",
-    "react-router-dom": "^7.0.2",
-    "react-scripts": "^5.0.0",
-    "react-toastify": "^11.0.2"
+    "react-router-dom": "^7.3.0",
+    "react-toastify": "^11.0.5"
   },
   "devDependencies": {
-    "@babel/plugin-proposal-private-property-in-object": "7.21.11",
-    "react-inject-env": "^2.1.0"
+    "@vitejs/plugin-react": "^4.3.4",
+    "depcheck": "^1.4.7",
+    "serve": "^14.2.4",
+    "vite": "^6.2.1"
   },
   "browserslist": {
     "production": [
diff --git a/cmd/experimental/kueue-viz/frontend/public/env.js b/cmd/experimental/kueue-viz/frontend/public/env.js
index 63649a035..264a57b2e 100644
--- a/cmd/experimental/kueue-viz/frontend/public/env.js
+++ b/cmd/experimental/kueue-viz/frontend/public/env.js
@@ -14,6 +14,9 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-export const env = { ...process.env, ...window['env'] }
+window.env = window.env || {
+  VITE_WEBSOCKET_URL: 'ws://localhost:8080',
+  REACT_APP_WEBSOCKET_URL: 'ws://localhost:8080'
+};
 
 
diff --git a/cmd/experimental/kueue-viz/frontend/src/App.js b/cmd/experimental/kueue-viz/frontend/src/App.jsx
similarity index 100%
rename from cmd/experimental/kueue-viz/frontend/src/App.js
rename to cmd/experimental/kueue-viz/frontend/src/App.jsx
diff --git a/cmd/experimental/kueue-viz/frontend/src/ClusterQueueDetail.js b/cmd/experimental/kueue-viz/frontend/src/ClusterQueueDetail.jsx
similarity index 100%
rename from cmd/experimental/kueue-viz/frontend/src/ClusterQueueDetail.js
rename to cmd/experimental/kueue-viz/frontend/src/ClusterQueueDetail.jsx
diff --git a/cmd/experimental/kueue-viz/frontend/src/ClusterQueues.js b/cmd/experimental/kueue-viz/frontend/src/ClusterQueues.jsx
similarity index 100%
rename from cmd/experimental/kueue-viz/frontend/src/ClusterQueues.js
rename to cmd/experimental/kueue-viz/frontend/src/ClusterQueues.jsx
diff --git a/cmd/experimental/kueue-viz/frontend/src/CohortDetail.js b/cmd/experimental/kueue-viz/frontend/src/CohortDetail.jsx
similarity index 100%
rename from cmd/experimental/kueue-viz/frontend/src/CohortDetail.js
rename to cmd/experimental/kueue-viz/frontend/src/CohortDetail.jsx
diff --git a/cmd/experimental/kueue-viz/frontend/src/Cohorts.js b/cmd/experimental/kueue-viz/frontend/src/Cohorts.jsx
similarity index 100%
rename from cmd/experimental/kueue-viz/frontend/src/Cohorts.js
rename to cmd/experimental/kueue-viz/frontend/src/Cohorts.jsx
diff --git a/cmd/experimental/kueue-viz/frontend/src/Dashboard.js b/cmd/experimental/kueue-viz/frontend/src/Dashboard.jsx
similarity index 100%
rename from cmd/experimental/kueue-viz/frontend/src/Dashboard.js
rename to cmd/experimental/kueue-viz/frontend/src/Dashboard.jsx
diff --git a/cmd/experimental/kueue-viz/frontend/src/FlavorTable.js b/cmd/experimental/kueue-viz/frontend/src/FlavorTable.jsx
similarity index 100%
rename from cmd/experimental/kueue-viz/frontend/src/FlavorTable.js
rename to cmd/experimental/kueue-viz/frontend/src/FlavorTable.jsx
diff --git a/cmd/experimental/kueue-viz/frontend/src/LocalQueueDetail.js b/cmd/experimental/kueue-viz/frontend/src/LocalQueueDetail.jsx
similarity index 100%
rename from cmd/experimental/kueue-viz/frontend/src/LocalQueueDetail.js
rename to cmd/experimental/kueue-viz/frontend/src/LocalQueueDetail.jsx
diff --git a/cmd/experimental/kueue-viz/frontend/src/LocalQueues.js b/cmd/experimental/kueue-viz/frontend/src/LocalQueues.jsx
similarity index 100%
rename from cmd/experimental/kueue-viz/frontend/src/LocalQueues.js
rename to cmd/experimental/kueue-viz/frontend/src/LocalQueues.jsx
diff --git a/cmd/experimental/kueue-viz/frontend/src/Navbar.js b/cmd/experimental/kueue-viz/frontend/src/Navbar.jsx
similarity index 100%
rename from cmd/experimental/kueue-viz/frontend/src/Navbar.js
rename to cmd/experimental/kueue-viz/frontend/src/Navbar.jsx
diff --git a/cmd/experimental/kueue-viz/frontend/src/ResourceFlavorDetail.js b/cmd/experimental/kueue-viz/frontend/src/ResourceFlavorDetail.jsx
similarity index 100%
rename from cmd/experimental/kueue-viz/frontend/src/ResourceFlavorDetail.js
rename to cmd/experimental/kueue-viz/frontend/src/ResourceFlavorDetail.jsx
diff --git a/cmd/experimental/kueue-viz/frontend/src/ResourceFlavors.js b/cmd/experimental/kueue-viz/frontend/src/ResourceFlavors.jsx
similarity index 100%
rename from cmd/experimental/kueue-viz/frontend/src/ResourceFlavors.js
rename to cmd/experimental/kueue-viz/frontend/src/ResourceFlavors.jsx
diff --git a/cmd/experimental/kueue-viz/frontend/src/WorkloadDetail.js b/cmd/experimental/kueue-viz/frontend/src/WorkloadDetail.jsx
similarity index 100%
rename from cmd/experimental/kueue-viz/frontend/src/WorkloadDetail.js
rename to cmd/experimental/kueue-viz/frontend/src/WorkloadDetail.jsx
diff --git a/cmd/experimental/kueue-viz/frontend/src/Workloads.js b/cmd/experimental/kueue-viz/frontend/src/Workloads.jsx
similarity index 100%
rename from cmd/experimental/kueue-viz/frontend/src/Workloads.js
rename to cmd/experimental/kueue-viz/frontend/src/Workloads.jsx
diff --git a/cmd/experimental/kueue-viz/frontend/src/WorkloadsList.js b/cmd/experimental/kueue-viz/frontend/src/WorkloadsList.jsx
similarity index 100%
rename from cmd/experimental/kueue-viz/frontend/src/WorkloadsList.js
rename to cmd/experimental/kueue-viz/frontend/src/WorkloadsList.jsx
diff --git a/cmd/experimental/kueue-viz/frontend/src/env.js b/cmd/experimental/kueue-viz/frontend/src/env.js
index 63649a035..607281aa6 100644
--- a/cmd/experimental/kueue-viz/frontend/src/env.js
+++ b/cmd/experimental/kueue-viz/frontend/src/env.js
@@ -14,6 +14,10 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-export const env = { ...process.env, ...window['env'] }
+// Combine Vite's environment variables with window.env
+export const env = { 
+  ...import.meta.env,
+  ...(window['env'] || {})
+}
 
 
diff --git a/cmd/experimental/kueue-viz/frontend/src/index.js b/cmd/experimental/kueue-viz/frontend/src/index.jsx
similarity index 100%
rename from cmd/experimental/kueue-viz/frontend/src/index.js
rename to cmd/experimental/kueue-viz/frontend/src/index.jsx
diff --git a/cmd/experimental/kueue-viz/frontend/start.sh b/cmd/experimental/kueue-viz/frontend/start.sh
new file mode 100755
index 000000000..ff130547b
--- /dev/null
+++ b/cmd/experimental/kueue-viz/frontend/start.sh
@@ -0,0 +1,42 @@
+#!/bin/sh
+
+# Copyright The Kubernetes Authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Generate env.js with runtime environment variables
+cat << EOF > ./build/env.js
+/*
+Copyright The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+window.env = {
+  VITE_WEBSOCKET_URL: "${REACT_APP_WEBSOCKET_URL:-ws://localhost:8080}",
+  REACT_APP_WEBSOCKET_URL: "${REACT_APP_WEBSOCKET_URL:-ws://localhost:8080}"
+};
+EOF
+
+# Start the server
+exec serve -s build -l 8080 
diff --git a/cmd/experimental/kueue-viz/frontend/vite.config.js b/cmd/experimental/kueue-viz/frontend/vite.config.js
new file mode 100644
index 000000000..97c9ffa5e
--- /dev/null
+++ b/cmd/experimental/kueue-viz/frontend/vite.config.js
@@ -0,0 +1,19 @@
+import { defineConfig } from 'vite';
+import react from '@vitejs/plugin-react';
+
+export default defineConfig({
+  plugins: [react()],
+  server: {
+    port: 3000, // Same port as react-scripts for consistency
+    open: true,
+  },
+  build: {
+    outDir: 'build', // Same output directory as react-scripts
+    sourcemap: true,
+  },
+  resolve: {
+    extensions: ['.js', '.jsx', '.json'],
+  },
+  publicDir: 'public',
+  envPrefix: ['VITE_', 'REACT_APP_'], // Support both VITE_ and REACT_APP_ prefixes
+}); 
\ No newline at end of file
diff --git a/cmd/kueue/main.go b/cmd/kueue/main.go
index afd6baf80..e132a090c 100644
--- a/cmd/kueue/main.go
+++ b/cmd/kueue/main.go
@@ -18,10 +18,12 @@ package main
 
 import (
 	"context"
+	"crypto/tls"
 	"errors"
 	"flag"
 	"net/http"
 	"os"
+	"path/filepath"
 
 	zaplog "go.uber.org/zap"
 	"go.uber.org/zap/zapcore"
@@ -39,6 +41,7 @@ import (
 	"k8s.io/client-go/util/flowcontrol"
 	"k8s.io/utils/ptr"
 	ctrl "sigs.k8s.io/controller-runtime"
+	"sigs.k8s.io/controller-runtime/pkg/certwatcher"
 	"sigs.k8s.io/controller-runtime/pkg/healthz"
 	"sigs.k8s.io/controller-runtime/pkg/log/zap"
 	"sigs.k8s.io/controller-runtime/pkg/metrics/filters"
@@ -153,6 +156,26 @@ func main() {
 		SecureServing:  true,
 		FilterProvider: filters.WithAuthenticationAndAuthorization,
 	}
+
+	if cfg.InternalCertManagement == nil || !*cfg.InternalCertManagement.Enable {
+		metricsCertPath := "/etc/kueue/metrics/certs"
+		setupLog.Info("Initializing metrics certificate watcher using provided certificates",
+			"metrics-cert-path", metricsCertPath)
+
+		var err error
+		metricsCertWatcher, err := certwatcher.New(
+			filepath.Join(metricsCertPath, "tls.crt"),
+			filepath.Join(metricsCertPath, "tls.key"),
+		)
+		if err != nil {
+			setupLog.Error(err, "Unable to initialize metrics certificate watcher")
+			os.Exit(1)
+		}
+
+		metricsServerOptions.TLSOpts = append(metricsServerOptions.TLSOpts, func(config *tls.Config) {
+			config.GetCertificate = metricsCertWatcher.GetCertificate
+		})
+	}
 	options.Metrics = metricsServerOptions
 
 	metrics.Register()
diff --git a/config/OWNERS b/config/OWNERS
new file mode 100644
index 000000000..ef7abba9d
--- /dev/null
+++ b/config/OWNERS
@@ -0,0 +1,5 @@
+# See the OWNERS docs at https://go.k8s.io/owners
+
+reviewers:
+- kannon92
+
diff --git a/config/components/certmanager/certificate-metrics.yaml b/config/components/certmanager/certificate-metrics.yaml
new file mode 100644
index 000000000..958cb7c16
--- /dev/null
+++ b/config/components/certmanager/certificate-metrics.yaml
@@ -0,0 +1,17 @@
+# The following manifests contain a metrics certificate CR.
+# More document can be found at https://docs.cert-manager.io
+apiVersion: cert-manager.io/v1
+kind: Certificate
+metadata:
+  name: metrics-certs  # this name should match the one appeared in kustomizeconfig.yaml
+  namespace: system
+spec:
+  dnsNames:
+  # SERVICE_NAME and SERVICE_NAMESPACE will be substituted by kustomize
+  # replacements in the config/default/kustomization.yaml file.
+  - SERVICE_NAME.SERVICE_NAMESPACE.svc
+  - SERVICE_NAME.SERVICE_NAMESPACE.svc.cluster.local
+  issuerRef:
+    kind: Issuer
+    name: selfsigned-issuer
+  secretName: metrics-server-cert
diff --git a/config/components/certmanager/kustomization.yaml b/config/components/certmanager/kustomization.yaml
index bebea5a59..fc1018507 100644
--- a/config/components/certmanager/kustomization.yaml
+++ b/config/components/certmanager/kustomization.yaml
@@ -1,5 +1,7 @@
 resources:
 - certificate.yaml
+- certificate-metrics.yaml
+
 
 configurations:
 - kustomizeconfig.yaml
diff --git a/config/components/crd/bases/kueue.x-k8s.io_workloads.yaml b/config/components/crd/bases/kueue.x-k8s.io_workloads.yaml
index 2f79cafed..c879bd310 100644
--- a/config/components/crd/bases/kueue.x-k8s.io_workloads.yaml
+++ b/config/components/crd/bases/kueue.x-k8s.io_workloads.yaml
@@ -8314,6 +8314,12 @@ spec:
                             SubGroupIndexLabel indicates the name of the label indexing the instances of replicated Jobs (groups)
                             within a PodSet. For example, in the context of JobSet this is jobset.sigs.k8s.io/job-index.
                           type: string
+                        unconstrained:
+                          description: |-
+                            unconstrained indicates that Kueue has the freedom to schedule the PodSet within
+                            the entire available capacity, without constraints on the compactness of the placement.
+                            This is indicated by the `kueue.x-k8s.io/podset-unconstrained-topology` PodSet annotation.
+                          type: boolean
                       type: object
                   required:
                   - count
diff --git a/config/components/prometheus/kustomization.yaml b/config/components/prometheus/kustomization.yaml
index 2363f098b..2a9620d35 100644
--- a/config/components/prometheus/kustomization.yaml
+++ b/config/components/prometheus/kustomization.yaml
@@ -1,3 +1,11 @@
 resources:
 - monitor.yaml
 - role.yaml
+# [PROMETHEUS-WITH-CERTS] The following patch configures the ServiceMonitor in ../prometheus
+# to securely reference certificates created and managed by cert-manager.
+# Additionally, ensure that you uncomment the [METRICS WITH CERTMANAGER] patch under config/default/kustomization.yaml
+# to mount the "metrics-server-cert" secret in the Manager Deployment.
+# patches:
+# - path: monitor_tls_patch.yaml
+#   target:
+#     kind: ServiceMonitor
diff --git a/config/components/prometheus/monitor_tls_patch.yaml b/config/components/prometheus/monitor_tls_patch.yaml
new file mode 100644
index 000000000..5bf84ce0d
--- /dev/null
+++ b/config/components/prometheus/monitor_tls_patch.yaml
@@ -0,0 +1,19 @@
+# Patch for Prometheus ServiceMonitor to enable secure TLS configuration
+# using certificates managed by cert-manager
+- op: replace
+  path: /spec/endpoints/0/tlsConfig
+  value:
+    # SERVICE_NAME and SERVICE_NAMESPACE will be substituted by kustomize
+    serverName: SERVICE_NAME.SERVICE_NAMESPACE.svc
+    insecureSkipVerify: false
+    ca:
+      secret:
+        name: metrics-server-cert
+        key: ca.crt
+    cert:
+      secret:
+        name: metrics-server-cert
+        key: tls.crt
+    keySecret:
+      name: metrics-server-cert
+      key: tls.key
diff --git a/config/default/cert_metrics_manager_patch.yaml b/config/default/cert_metrics_manager_patch.yaml
new file mode 100644
index 000000000..78fc5929f
--- /dev/null
+++ b/config/default/cert_metrics_manager_patch.yaml
@@ -0,0 +1,25 @@
+# This patch adds the args, volumes, and ports to allow the manager to use the metrics-server certs.
+
+# Add the volumeMount for the metrics-server certs
+- op: add
+  path: /spec/template/spec/containers/0/volumeMounts/-
+  value:
+    mountPath: /etc/kueue/metrics/certs
+    name: metrics-certs
+    readOnly: true
+
+# Add the metrics-server certs volume configuration
+- op: add
+  path: /spec/template/spec/volumes/-
+  value:
+    name: metrics-certs
+    secret:
+      secretName: metrics-server-cert
+      optional: false
+      items:
+        - key: ca.crt
+          path: ca.crt
+        - key: tls.crt
+          path: tls.crt
+        - key: tls.key
+          path: tls.key
diff --git a/config/default/kustomization.yaml b/config/default/kustomization.yaml
index c547ad1d3..18a0dc483 100644
--- a/config/default/kustomization.yaml
+++ b/config/default/kustomization.yaml
@@ -29,7 +29,7 @@ resources:
 # [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 'WEBHOOK' components are required.
 # - ../components/certmanager
 # [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'.
-#- ../components/prometheus
+# - ../components/prometheus
 # [METRICS] Expose the controller manager metrics service.
 - metrics_service.yaml
 
@@ -58,6 +58,13 @@ patches:
 # - path: mutating_webhookcainjection_patch.yaml
 # - path: validating_webhookcainjection_patch.yaml
 
+# Uncomment the patches line if you enable Metrics and CertManager
+# [CERTMANAGER] To enable metrics protected with certManager, uncomment the following line.
+# This patch will protect the metrics with certManager self-signed certs.
+# - path: cert_metrics_manager_patch.yaml
+#  target:
+#    kind: Deployment
+
 
 # the following config is for teaching kustomize how to do var substitution
 # vars:
diff --git a/keps/2724-topology-aware-scheduling/README.md b/keps/2724-topology-aware-scheduling/README.md
index 6ea92bb75..4eefae794 100644
--- a/keps/2724-topology-aware-scheduling/README.md
+++ b/keps/2724-topology-aware-scheduling/README.md
@@ -29,6 +29,7 @@
   - [Internal APIs](#internal-apis)
   - [Implicit defaulting of TAS annotations](#implicit-defaulting-of-tas-annotations)
   - [Computing the assignment](#computing-the-assignment)
+    - [Example](#example)
   - [Enforcing the assignment](#enforcing-the-assignment)
   - [Test Plan](#test-plan)
       - [Prerequisite testing updates](#prerequisite-testing-updates)
@@ -430,6 +431,14 @@ const (
   // at the highest topology level, then it gets admitted as distributed
   // among multiple topology domains.
   PodSetPreferredTopologyAnnotation = "kueue.x-k8s.io/podset-preferred-topology"
+
+  // PodSetUnconstrainedTopologyAnnotation indicates that a PodSet does not have any topology requirements.
+  // Kueue admits the PodSet if there's enough free capacity available.
+  // Recommended for PodSets that don't need low-latency or high-throughput pod-to-pod communication,
+  // but want to leverage TAS capabilities improve accuracy of admitting jobs
+  //
+  // +kubebuilder:validation:Type=boolean
+  PodSetUnconstrainedTopologyAnnotation = "kueue.x-k8s.io/podset-unconstrained-topology"
 )
 ```
 
@@ -448,6 +457,10 @@ the rules is deactivated):
 - if "podset-required-topology" or "podset-preferred-topology" is specified for
   one PodTemplate, then one of them is specified for every PodTemplate in the
   Job spec.
+- the annotations `kueue.x-k8s.io/podset-required-topology`,
+  `kueue.x-k8s.io/podset-preferred-topology`, and `kueue.x-k8s.io/podset-unconstrained-topology`
+  are mutually exclusive.
+
 
 ### Internal APIs
 
@@ -478,6 +491,14 @@ type PodSetTopologyRequest struct {
   // +optional
   Preferred *string `json:"preferred,omitempty"`
 
+  // unconstrained indicates that Kueue has the freedom to schedule the PodSet within
+  // the entire available capacity, without constraints on the compactness of the placement.
+  // This is indicated by the `kueue.x-k8s.io/podset-unconstrained-topology` PodSet annotation.
+  //
+  // +optional
+  // +kubebuilder:validation:Type=boolean
+  Unconstrained *bool `json:"unconstrained,omitempty"`
+
   // PodIndexLabel indicates the name of the label indexing the pods.
   // For example, in the context of
   // - kubernetes job this is: kubernetes.io/job-completion-index
@@ -632,7 +653,7 @@ targetting CQs with only TAS Resource Flavors (RFs with the `spec.topologyName`
 field specified).
 
 A PodSet scheduled with TAS without the explicit annotation is handled as
-if it had the `podset-preferred-topology` annotation pointing to the lowest
+if it had the `podset-unconstrained-topology: true` annotation pointing to the lowest
 topology level defined in the Topology referenced by the selected TAS flavor.
 We call it "implicit default" as the annotation isn't persisted.
 
@@ -663,11 +684,37 @@ For a given PodSet Kueue:
   level. Kueue starts the search from the specified level, but if the PodSet
   does not fit, then it tries higher levels in the hierarchy.
 
-Kueue packs pods on domains starting from the domains with the most free capacity. However, Kueue can operate in two modes when it comes to choosing the last domain if there is more than one capable of accommodating the remaining pods:
-- `MostAllocated` - Kueue chooses the domain with the least available resource that is capable of accommodating all the pods to mitigate resource fragmentation
-- `LeastAllocated` - Kueue chooses the domain that has the most available resources, providing better nodes utilization
+Kueue places pods on domains with different algorithms, depending on the annotation and chosen profile:
+- `MostFreeCapacity` algorithm - Kueue selects as many domains as needed (if it meets user's requirement) starting from the one with the most free capacity;
+- `LeastFreeCapacity` algorithm - Kueue selects as many domains as needed (if it meets user's requirement) starting from the one with the least free capacity;
+- `BestFit` algorithm (default) - Kueue selects as many domains as needed (if it meets user's requirement) starting from the one with the most free capacity.
+However, it optimizes the selection of the last domain at each level to minimize the remaining free resources.
+
+#### Example
+Consider a rack with four nodes that can accommodate 3, 3, 2, and 1 pod, respectively. A PodSet consists of 7 pods.
+
+Both the BestFit and MostFreeCapacity algorithms will initially iterate over the nodes and select the first two nodes,
+each with 3 available pods, as they possess the most free capacity. With 1 pod remaining to schedule, the difference between the algorithms becomes apparent:
+- The `BestFit` algorithm optimizes the choice of the last node (domain) and selects the node that can accommodate exactly 1 pod.
+- The `MostFreeCapacity` algorithm simply selects the node with the most remaining free capacity, which is 2 in this case.
+
+The `LeastFreeCapacity` algorithm iterates over the nodes in reverse order.
+Consequently, it selects the nodes with 1, 2, 3, and 3 available pods, reserving capacity for only 1 pod on the last node.
+
+Selection of the algorithm depends on TAS profiles expressed by feature gates, and PodSet's annotation:
+
+| featuregate/annotation                   | preferred         | required          | unconstrained     |
+| ---------------------------------------- | ----------------- | ----------------- | ----------------- |
+| None                                     | BestFit           | BestFit           | BestFit           |
+| TASProfileMostFreeCapacity (deprecated)  | MostFreeCapacity  | MostFreeCapacity  | MostFreeCapacity  |
+| TASProfileMixed (deprecated)             | BestFit           | BestFit           | LeastFreeCapacity |
+| TASProfileLeastFreeCapacity (deprecated) | LeastFreeCapacity | LeastFreeCapacity | LeastFreeCapacity |
+
+Feature gates: `TASProfileLeastAllocated`, `TASProfileMixed` and `TASProfileLeastFreeCapacity` are mutually exclusive.
 
-By default Kueue uses the `MostAllocated` algorithm. To use `LeastAllocated` algorithm, a user needs to set the feature gate `TASLeastAllocated` to `true`
+We recommend the BestFit algorithm for most of use cases, however we give more flexibility to users with those experimental feature gates.
+Based on the collected feedback we will introduce TAS configuration that would allow user to select the desired algorithm.
+Eventually we'll remove the feature as they will be no longer need when we implement API for TAS configuration.
 
 ### Enforcing the assignment
 
@@ -762,6 +809,7 @@ The new validations which are for MVP, but likely will be relaxed in the future:
   for node taints. Some options to consider include virtual level as proposed in
   the [issue](https://github.com/kubernetes-sigs/kueue/issues/3658#issuecomment-2505583333)
   or explicit level added by webhook.
+- introduce configuration for setting TAS profiles/algorithms
 
 #### Stable
 
diff --git a/keps/2724-topology-aware-scheduling/kep.yaml b/keps/2724-topology-aware-scheduling/kep.yaml
index 289c51900..c1de42aa1 100644
--- a/keps/2724-topology-aware-scheduling/kep.yaml
+++ b/keps/2724-topology-aware-scheduling/kep.yaml
@@ -31,7 +31,9 @@ milestone:
 # List the feature gate name and the components for which it must be enabled
 feature-gates:
   - name: TopologyAwareScheduling
-  - name: TASMostFreeCapacity
+  - name: TASProfileLeastAllocated
+  - name: TASProfileMixed
+  - name: TASProfileLeastFreeCapacity
 disable-supported: true
 
 # The following PRR answers are required at beta release
diff --git a/pkg/cache/clusterqueue_snapshot.go b/pkg/cache/clusterqueue_snapshot.go
index 16548e2e5..b993089d7 100644
--- a/pkg/cache/clusterqueue_snapshot.go
+++ b/pkg/cache/clusterqueue_snapshot.go
@@ -69,11 +69,11 @@ func (c *ClusterQueueSnapshot) RGByResource(resource corev1.ResourceName) *Resou
 	return nil
 }
 
-// SimulateUsageRemoval the snapshot by removing the usage corresponding to the
-// list of workloads. It returns the function which can be used to restore
-// the usage.
-func (c *ClusterQueueSnapshot) SimulateUsageRemoval(workloads []*workload.Info) func() {
-	var usage []workload.Usage
+// SimulateWorkloadRemoval modifies the snapshot by removing the usage
+// corresponding to the list of workloads. It returns a function which
+// can be used to restore the usage.
+func (c *ClusterQueueSnapshot) SimulateWorkloadRemoval(workloads []*workload.Info) func() {
+	usage := make([]workload.Usage, 0, len(workloads))
 	for _, w := range workloads {
 		usage = append(usage, w.Usage())
 	}
@@ -87,6 +87,24 @@ func (c *ClusterQueueSnapshot) SimulateUsageRemoval(workloads []*workload.Info)
 	}
 }
 
+// SimulateUsageAddition modifies the snapshot by adding usage, and
+// returns a function used to restore the usage.
+func (c *ClusterQueueSnapshot) SimulateUsageAddition(usage workload.Usage) func() {
+	c.AddUsage(usage)
+	return func() {
+		c.RemoveUsage(usage)
+	}
+}
+
+// SimulateUsageRemoval modifies the snapshot by removing usage, and
+// returns a function used to restore the usage.
+func (c *ClusterQueueSnapshot) SimulateUsageRemoval(usage workload.Usage) func() {
+	c.RemoveUsage(usage)
+	return func() {
+		c.AddUsage(usage)
+	}
+}
+
 func (c *ClusterQueueSnapshot) AddUsage(usage workload.Usage) {
 	for fr, q := range usage.Quota {
 		addUsage(c, fr, q)
@@ -183,11 +201,6 @@ func (c *ClusterQueueSnapshot) DominantResourceShare() int {
 	return share
 }
 
-func (c *ClusterQueueSnapshot) DominantResourceShareWith(wlReq resources.FlavorResourceQuantities) int {
-	share, _ := dominantResourceShare(c, wlReq)
-	return share
-}
-
 func (c *ClusterQueueSnapshot) DominantResourceShareWithout(wlReq resources.FlavorResourceQuantities) int {
 	without := maps.Clone(wlReq)
 	for fr, q := range without {
diff --git a/pkg/cache/tas_flavor_snapshot.go b/pkg/cache/tas_flavor_snapshot.go
index 358d4ce91..f525bb33b 100644
--- a/pkg/cache/tas_flavor_snapshot.go
+++ b/pkg/cache/tas_flavor_snapshot.go
@@ -332,7 +332,6 @@ type FailureInfo struct {
 	Reason string
 }
 
-// the key in this map is PodSet name
 type TASAssignmentsResult map[kueue.PodSetReference]tasPodSetAssignmentResult
 
 func (r TASAssignmentsResult) Failure() *FailureInfo {
@@ -414,6 +413,7 @@ func (s *TASFlavorSnapshot) findTopologyAssignment(
 	count := tasPodSetRequests.Count
 	required := isRequired(tasPodSetRequests.PodSet.TopologyRequest)
 	key := s.levelKeyWithImpliedFallback(&tasPodSetRequests)
+	unconstrained := isUnconstrained(tasPodSetRequests.PodSet.TopologyRequest, &tasPodSetRequests)
 	if key == nil {
 		return nil, "topology level not specified"
 	}
@@ -426,24 +426,25 @@ func (s *TASFlavorSnapshot) findTopologyAssignment(
 
 	// phase 2a: determine the level at which the assignment is done along with
 	// the domains which can accommodate all pods
-	fitLevelIdx, currFitDomain, reason := s.findLevelWithFitDomains(levelIdx, required, count)
+	fitLevelIdx, currFitDomain, reason := s.findLevelWithFitDomains(levelIdx, required, count, unconstrained)
 	if len(reason) > 0 {
 		return nil, reason
 	}
 
 	// phase 2b: traverse the tree down level-by-level optimizing the number of
 	// topology domains at each level
-	currFitDomain = s.updateCountsToMinimum(currFitDomain, count)
+	// if unconstrained is set, we'll only do it once
+	currFitDomain = s.updateCountsToMinimum(currFitDomain, count, unconstrained)
 	for levelIdx := fitLevelIdx; levelIdx+1 < len(s.domainsPerLevel); levelIdx++ {
 		lowerFitDomains := s.lowerLevelDomains(currFitDomain)
-		sortedLowerDomains := s.sortedDomains(lowerFitDomains)
-		currFitDomain = s.updateCountsToMinimum(sortedLowerDomains, count)
+		sortedLowerDomains := s.sortedDomains(lowerFitDomains, unconstrained)
+		currFitDomain = s.updateCountsToMinimum(sortedLowerDomains, count, unconstrained)
 	}
 	return s.buildAssignment(currFitDomain), ""
 }
 
 func (s *TASFlavorSnapshot) HasLevel(r *kueue.PodSetTopologyRequest) bool {
-	key := levelKey(r)
+	key := s.levelKey(r)
 	if key == nil {
 		return false
 	}
@@ -464,7 +465,7 @@ func isRequired(tr *kueue.PodSetTopologyRequest) bool {
 }
 
 func (s *TASFlavorSnapshot) levelKeyWithImpliedFallback(tasRequests *TASPodSetRequests) *string {
-	if key := levelKey(tasRequests.PodSet.TopologyRequest); key != nil {
+	if key := s.levelKey(tasRequests.PodSet.TopologyRequest); key != nil {
 		return key
 	}
 	if tasRequests.Implied {
@@ -473,16 +474,24 @@ func (s *TASFlavorSnapshot) levelKeyWithImpliedFallback(tasRequests *TASPodSetRe
 	return nil
 }
 
-func levelKey(topologyRequest *kueue.PodSetTopologyRequest) *string {
+func (s *TASFlavorSnapshot) levelKey(topologyRequest *kueue.PodSetTopologyRequest) *string {
 	if topologyRequest == nil {
 		return nil
 	}
-	if topologyRequest.Required != nil {
+	switch {
+	case topologyRequest.Required != nil:
 		return topologyRequest.Required
-	} else if topologyRequest.Preferred != nil {
+	case topologyRequest.Preferred != nil:
 		return topologyRequest.Preferred
+	case ptr.Deref(topologyRequest.Unconstrained, false):
+		return ptr.To(s.lowestLevel())
+	default:
+		return nil
 	}
-	return nil
+}
+
+func isUnconstrained(tr *kueue.PodSetTopologyRequest, tasRequests *TASPodSetRequests) bool {
+	return (tr != nil && tr.Unconstrained != nil && *tr.Unconstrained) || tasRequests.Implied
 }
 
 // findBestFitDomainIdx finds an index of the first domain with the lowest
@@ -501,29 +510,31 @@ func findBestFitDomainIdx(domains []*domain, count int32) int {
 	return bestFitIdx
 }
 
-func (s *TASFlavorSnapshot) findLevelWithFitDomains(levelIdx int, required bool, count int32) (int, []*domain, string) {
+func (s *TASFlavorSnapshot) findLevelWithFitDomains(levelIdx int, required bool, count int32, unconstrained bool) (int, []*domain, string) {
 	domains := s.domainsPerLevel[levelIdx]
 	if len(domains) == 0 {
 		return 0, nil, fmt.Sprintf("no topology domains at level: %s", s.levelKeys[levelIdx])
 	}
 	levelDomains := slices.Collect(maps.Values(domains))
-	sortedDomain := s.sortedDomains(levelDomains)
+	sortedDomain := s.sortedDomains(levelDomains, unconstrained)
 	topDomain := sortedDomain[0]
-	if !features.Enabled(features.TASMostFreeCapacity) && topDomain.state >= count {
+	if useBestFitAlgorithm(unconstrained) && topDomain.state >= count {
+		// optimize the potentially last domain
 		topDomain = sortedDomain[findBestFitDomainIdx(sortedDomain, count)]
 	}
 	if topDomain.state < count {
 		if required {
 			return 0, nil, s.notFitMessage(topDomain.state, count)
 		}
-		if levelIdx > 0 {
-			return s.findLevelWithFitDomains(levelIdx-1, required, count)
+		if levelIdx > 0 && !unconstrained {
+			return s.findLevelWithFitDomains(levelIdx-1, required, count, unconstrained)
 		}
 		results := []*domain{}
 		remainingCount := count
 		for idx := 0; remainingCount > 0 && idx < len(sortedDomain) && sortedDomain[idx].state > 0; idx++ {
 			offset := 0
-			if !features.Enabled(features.TASMostFreeCapacity) && sortedDomain[idx].state >= remainingCount {
+			if useBestFitAlgorithm(unconstrained) && sortedDomain[idx].state >= remainingCount {
+				// optimize the last domain
 				offset = findBestFitDomainIdx(sortedDomain[idx:], remainingCount)
 			}
 			results = append(results, sortedDomain[idx+offset])
@@ -532,18 +543,38 @@ func (s *TASFlavorSnapshot) findLevelWithFitDomains(levelIdx int, required bool,
 		if remainingCount > 0 {
 			return 0, nil, s.notFitMessage(count-remainingCount, count)
 		}
-		return 0, results, ""
+		return levelIdx, results, ""
 	}
 	return levelIdx, []*domain{topDomain}, ""
 }
 
-func (s *TASFlavorSnapshot) updateCountsToMinimum(domains []*domain, count int32) []*domain {
+func useBestFitAlgorithm(unconstrained bool) bool {
+	if features.Enabled(features.TASProfileMostFreeCapacity) ||
+		features.Enabled(features.TASProfileLeastFreeCapacity) ||
+		(unconstrained && features.Enabled(features.TASProfileMixed)) {
+		// following the matrix from KEP#2724
+		return false
+	}
+	return true
+}
+
+func useLeastFreeCapacityAlgorithm(unconstrained bool) bool {
+	if features.Enabled(features.TASProfileLeastFreeCapacity) ||
+		(unconstrained && features.Enabled(features.TASProfileMixed)) {
+		// following the matrix from KEP#2724
+		return true
+	}
+	return false
+}
+
+func (s *TASFlavorSnapshot) updateCountsToMinimum(domains []*domain, count int32, unconstrained bool) []*domain {
 	result := make([]*domain, 0)
 	remainingCount := count
 	for i, domain := range domains {
-		if !features.Enabled(features.TASMostFreeCapacity) && domain.state >= remainingCount {
-			bestFitIdx := findBestFitDomainIdx(domains[i:], remainingCount)
-			domain = domains[i+bestFitIdx]
+		if useBestFitAlgorithm(unconstrained) && domain.state >= remainingCount {
+			// optimize the last domain
+			mostAllocatedIdx := findBestFitDomainIdx(domains[i:], remainingCount)
+			domain = domains[i+mostAllocatedIdx]
 		}
 
 		if domain.state >= remainingCount {
@@ -597,7 +628,7 @@ func (s *TASFlavorSnapshot) lowerLevelDomains(domains []*domain) []*domain {
 	return result
 }
 
-func (s *TASFlavorSnapshot) sortedDomains(domains []*domain) []*domain {
+func (s *TASFlavorSnapshot) sortedDomains(domains []*domain, unconstrained bool) []*domain {
 	result := slices.Clone(domains)
 	slices.SortFunc(result, func(a, b *domain) int {
 		if a.state == b.state {
@@ -606,6 +637,10 @@ func (s *TASFlavorSnapshot) sortedDomains(domains []*domain) []*domain {
 		// descending order.
 		return cmp.Compare(b.state, a.state)
 	})
+	if useLeastFreeCapacityAlgorithm(unconstrained) {
+		// start from the domain with the least amount of free resources
+		slices.Reverse(result)
+	}
 	return result
 }
 
diff --git a/pkg/config/validation.go b/pkg/config/validation.go
index 6341074c6..1600f5a88 100644
--- a/pkg/config/validation.go
+++ b/pkg/config/validation.go
@@ -360,5 +360,22 @@ func ValidateFeatureGates(featureGateCLI string, featureGateMap map[string]bool)
 	if featureGateCLI != "" && featureGateMap != nil {
 		return errors.New("feature gates for CLI and configuration cannot both specified")
 	}
+	TASProfilesEnabled := []bool{features.Enabled(features.TASProfileMixed),
+		features.Enabled(features.TASProfileLeastFreeCapacity),
+		features.Enabled(features.TASProfileMostFreeCapacity),
+	}
+	enabledProfilesCount := 0
+	for _, enabled := range TASProfilesEnabled {
+		if enabled {
+			enabledProfilesCount++
+		}
+	}
+	if enabledProfilesCount > 1 {
+		return errors.New("Cannot use more than one TAS profiles")
+	}
+	if !features.Enabled(features.TopologyAwareScheduling) && enabledProfilesCount > 0 {
+		return errors.New("Cannot use a TAS profile with TAS disabled")
+	}
+
 	return nil
 }
diff --git a/pkg/controller/admissionchecks/multikueue/controllers.go b/pkg/controller/admissionchecks/multikueue/controllers.go
index 9c00ff57e..c46bf1c5d 100644
--- a/pkg/controller/admissionchecks/multikueue/controllers.go
+++ b/pkg/controller/admissionchecks/multikueue/controllers.go
@@ -73,7 +73,7 @@ func WithEventsBatchPeriod(d time.Duration) SetupOption {
 	}
 }
 
-// WithAdapter - sets or updates the adapter of the MultiKueue adapters.
+// WithAdapters sets or updates the adapters of the MultiKueue adapters.
 func WithAdapters(adapters map[string]jobframework.MultiKueueAdapter) SetupOption {
 	return func(o *SetupOptions) {
 		o.adapters = adapters
diff --git a/pkg/controller/core/clusterqueue_controller.go b/pkg/controller/core/clusterqueue_controller.go
index a284d7435..88e71f634 100644
--- a/pkg/controller/core/clusterqueue_controller.go
+++ b/pkg/controller/core/clusterqueue_controller.go
@@ -210,8 +210,8 @@ func (r *ClusterQueueReconciler) Reconcile(ctx context.Context, req ctrl.Request
 	return ctrl.Result{}, nil
 }
 
-// Only topology Creation or Delete can impact the CQ active state, so we
-// ignore other updates
+// NotifyTopologyUpdate triggers a topology update event only on creation or deletion,
+// as these are the only changes affecting the ClusterQueue's active state.
 func (r *ClusterQueueReconciler) NotifyTopologyUpdate(oldTopology, newTopology *kueuealpha.Topology) {
 	// if oldTopology is nil, it's a create event.
 	if oldTopology == nil {
diff --git a/pkg/controller/jobframework/tas.go b/pkg/controller/jobframework/tas.go
index 9cebfd4d4..e08a0b9a2 100644
--- a/pkg/controller/jobframework/tas.go
+++ b/pkg/controller/jobframework/tas.go
@@ -17,6 +17,8 @@ limitations under the License.
 package jobframework
 
 import (
+	"strconv"
+
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	kueuealpha "sigs.k8s.io/kueue/apis/kueue/v1alpha1"
@@ -26,17 +28,22 @@ import (
 func PodSetTopologyRequest(meta *metav1.ObjectMeta, podIndexLabel *string, subGroupIndexLabel *string, subGroupCount *int32) *kueue.PodSetTopologyRequest {
 	requiredValue, requiredFound := meta.Annotations[kueuealpha.PodSetRequiredTopologyAnnotation]
 	preferredValue, preferredFound := meta.Annotations[kueuealpha.PodSetPreferredTopologyAnnotation]
+	unconstrained, unconstrainedFound := meta.Annotations[kueuealpha.PodSetUnconstrainedTopologyAnnotation]
 
-	if requiredFound || preferredFound {
+	if requiredFound || preferredFound || unconstrainedFound {
 		psTopologyReq := &kueue.PodSetTopologyRequest{
 			PodIndexLabel:      podIndexLabel,
 			SubGroupIndexLabel: subGroupIndexLabel,
 			SubGroupCount:      subGroupCount,
 		}
-		if requiredFound {
+		switch {
+		case requiredFound:
 			psTopologyReq.Required = &requiredValue
-		} else {
+		case preferredFound:
 			psTopologyReq.Preferred = &preferredValue
+		case unconstrainedFound:
+			unconstrained, _ := strconv.ParseBool(unconstrained)
+			psTopologyReq.Unconstrained = &unconstrained
 		}
 		return psTopologyReq
 	}
diff --git a/pkg/controller/jobframework/tas_validation.go b/pkg/controller/jobframework/tas_validation.go
index 5a672381e..a94c11c5a 100644
--- a/pkg/controller/jobframework/tas_validation.go
+++ b/pkg/controller/jobframework/tas_validation.go
@@ -30,12 +30,20 @@ func ValidateTASPodSetRequest(replicaPath *field.Path, replicaMetadata *metav1.O
 	var allErrs field.ErrorList
 	requiredValue, requiredFound := replicaMetadata.Annotations[kueuealpha.PodSetRequiredTopologyAnnotation]
 	preferredValue, preferredFound := replicaMetadata.Annotations[kueuealpha.PodSetPreferredTopologyAnnotation]
+	_, unconstrainedFound := replicaMetadata.Annotations[kueuealpha.PodSetUnconstrainedTopologyAnnotation]
+	annotationFoundCount := 0
+	for _, found := range []bool{requiredFound, preferredFound, unconstrainedFound} {
+		if found {
+			annotationFoundCount++
+		}
+	}
 	annotationsPath := replicaPath.Child("annotations")
-	if requiredFound && preferredFound {
+	if annotationFoundCount > 1 {
 		allErrs = append(allErrs, field.Invalid(annotationsPath, field.OmitValueType{},
-			fmt.Sprintf("must not contain both %q and %q",
+			fmt.Sprintf("must not contain more than one topology annotation: [%q, %q, %q]",
 				kueuealpha.PodSetRequiredTopologyAnnotation,
-				kueuealpha.PodSetPreferredTopologyAnnotation),
+				kueuealpha.PodSetPreferredTopologyAnnotation,
+				kueuealpha.PodSetUnconstrainedTopologyAnnotation),
 		))
 	}
 	if requiredFound {
diff --git a/pkg/controller/jobframework/webhook/builder.go b/pkg/controller/jobframework/webhook/builder.go
index 081d9d58c..f8c9dfb48 100644
--- a/pkg/controller/jobframework/webhook/builder.go
+++ b/pkg/controller/jobframework/webhook/builder.go
@@ -69,7 +69,7 @@ func (blder *WebhookBuilder) For(apiType runtime.Object) *WebhookBuilder {
 	return blder
 }
 
-// WithDefaulter takes an admission.CustomDefaulter interface, a MutatingWebhook will be wired for this type.
+// WithMutationHandler takes an admission.CustomDefaulter interface, a MutatingWebhook will be wired for this type.
 func (blder *WebhookBuilder) WithMutationHandler(h admission.Handler) *WebhookBuilder {
 	blder.mutationHandler = h
 	return blder
diff --git a/pkg/controller/jobs/jobset/OWNERS b/pkg/controller/jobs/jobset/OWNERS
new file mode 100644
index 000000000..ef7abba9d
--- /dev/null
+++ b/pkg/controller/jobs/jobset/OWNERS
@@ -0,0 +1,5 @@
+# See the OWNERS docs at https://go.k8s.io/owners
+
+reviewers:
+- kannon92
+
diff --git a/pkg/controller/tas/resource_flavor.go b/pkg/controller/tas/resource_flavor.go
index 0e653a439..9e5a5516a 100644
--- a/pkg/controller/tas/resource_flavor.go
+++ b/pkg/controller/tas/resource_flavor.go
@@ -18,7 +18,6 @@ package tas
 
 import (
 	"context"
-	"time"
 
 	corev1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/types"
@@ -37,14 +36,11 @@ import (
 	kueuealpha "sigs.k8s.io/kueue/apis/kueue/v1alpha1"
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta1"
 	"sigs.k8s.io/kueue/pkg/cache"
+	"sigs.k8s.io/kueue/pkg/constants"
 	"sigs.k8s.io/kueue/pkg/controller/core"
 	"sigs.k8s.io/kueue/pkg/queue"
 )
 
-const (
-	nodeBatchPeriod = time.Second
-)
-
 type rfReconciler struct {
 	queues   *queue.Manager
 	cache    *cache.Cache
@@ -125,7 +121,7 @@ func (h *nodeHandler) queueReconcileForNode(node *corev1.Node, q workqueue.Typed
 		if nodeBelongsToFlavor(node, flavor.NodeLabels, flavor.Levels) {
 			q.AddAfter(reconcile.Request{NamespacedName: types.NamespacedName{
 				Name: string(name),
-			}}, nodeBatchPeriod)
+			}}, constants.UpdatesBatchPeriod)
 		}
 	}
 }
diff --git a/pkg/controller/tas/topology_controller.go b/pkg/controller/tas/topology_controller.go
index 0cc35b077..74032d715 100644
--- a/pkg/controller/tas/topology_controller.go
+++ b/pkg/controller/tas/topology_controller.go
@@ -37,6 +37,7 @@ import (
 	kueuealpha "sigs.k8s.io/kueue/apis/kueue/v1alpha1"
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta1"
 	"sigs.k8s.io/kueue/pkg/cache"
+	"sigs.k8s.io/kueue/pkg/constants"
 	"sigs.k8s.io/kueue/pkg/controller/core"
 	"sigs.k8s.io/kueue/pkg/controller/tas/indexer"
 	"sigs.k8s.io/kueue/pkg/queue"
@@ -206,5 +207,5 @@ func (h *resourceFlavorHandler) Delete(_ context.Context, e event.DeleteEvent, q
 		NamespacedName: types.NamespacedName{
 			Name: string(*resourceFlavor.Spec.TopologyName),
 		},
-	}, nodeBatchPeriod)
+	}, constants.UpdatesBatchPeriod)
 }
diff --git a/pkg/controller/tas/topology_ungater.go b/pkg/controller/tas/topology_ungater.go
index 386b08ab3..e8e5d4498 100644
--- a/pkg/controller/tas/topology_ungater.go
+++ b/pkg/controller/tas/topology_ungater.go
@@ -21,7 +21,6 @@ import (
 	"errors"
 	"fmt"
 	"slices"
-	"time"
 
 	"github.com/go-logr/logr"
 	corev1 "k8s.io/api/core/v1"
@@ -40,6 +39,7 @@ import (
 	configapi "sigs.k8s.io/kueue/apis/config/v1beta1"
 	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/core"
 	"sigs.k8s.io/kueue/pkg/controller/tas/indexer"
 	utilclient "sigs.k8s.io/kueue/pkg/util/client"
@@ -51,10 +51,6 @@ import (
 	"sigs.k8s.io/kueue/pkg/workload"
 )
 
-const (
-	ungateBatchPeriod = time.Second
-)
-
 var (
 	errPendingUngateOps = errors.New("pending ungate operations")
 )
@@ -142,7 +138,7 @@ func (h *podHandler) queueReconcileForPod(ctx context.Context, object client.Obj
 			log := ctrl.LoggerFrom(ctx).WithValues("pod", klog.KObj(pod), "workload", key.String())
 			h.expectationsStore.ObservedUID(log, key, pod.UID)
 		}
-		q.AddAfter(reconcile.Request{NamespacedName: key}, ungateBatchPeriod)
+		q.AddAfter(reconcile.Request{NamespacedName: key}, constants.UpdatesBatchPeriod)
 	}
 }
 
diff --git a/pkg/features/kube_features.go b/pkg/features/kube_features.go
index 4227e94c2..70daec9c3 100644
--- a/pkg/features/kube_features.go
+++ b/pkg/features/kube_features.go
@@ -150,7 +150,19 @@ const (
 	// kep: https://github.com/kubernetes-sigs/kueue/tree/main/keps/2724-topology-aware-scheduling
 	//
 	// Enable to set use LeastAlloactedFit algorithm for TAS
-	TASMostFreeCapacity featuregate.Feature = "TASMostFreeCapacity"
+	TASProfileMostFreeCapacity featuregate.Feature = "TASProfileMostFreeCapacity"
+
+	// owner: @pbundyra
+	// kep: https://github.com/kubernetes-sigs/kueue/tree/main/keps/2724-topology-aware-scheduling
+	//
+	// Enable to set use LeastAlloactedFit algorithm for TAS
+	TASProfileLeastFreeCapacity featuregate.Feature = "TASProfileLeastFreeCapacity"
+
+	// owner: @pbundyra
+	// kep: https://github.com/kubernetes-sigs/kueue/tree/main/keps/2724-topology-aware-scheduling
+	//
+	// Enable to set use LeastAlloactedFit algorithm for TAS
+	TASProfileMixed featuregate.Feature = "TASProfileMixed"
 )
 
 func init() {
@@ -231,7 +243,13 @@ var defaultVersionedFeatureGates = map[featuregate.Feature]featuregate.Versioned
 	LocalQueueDefaulting: {
 		{Version: version.MustParse("0.10"), Default: false, PreRelease: featuregate.Alpha},
 	},
-	TASMostFreeCapacity: {
+	TASProfileMostFreeCapacity: {
+		{Version: version.MustParse("0.11"), Default: false, PreRelease: featuregate.Deprecated},
+	},
+	TASProfileLeastFreeCapacity: {
+		{Version: version.MustParse("0.11"), Default: false, PreRelease: featuregate.Deprecated},
+	},
+	TASProfileMixed: {
 		{Version: version.MustParse("0.11"), Default: false, PreRelease: featuregate.Deprecated},
 	},
 }
diff --git a/pkg/hierarchy/cycle.go b/pkg/hierarchy/cycle.go
index f6baacfa5..f1635a54c 100644
--- a/pkg/hierarchy/cycle.go
+++ b/pkg/hierarchy/cycle.go
@@ -24,7 +24,7 @@ type CycleCheckable[T comparable] interface {
 	CCParent() CycleCheckable[T]
 }
 
-// cycleChecker checks for cycles in Cohorts, while memoizing the
+// CycleChecker checks for cycles in Cohorts, while memorizing the
 // result.
 type CycleChecker struct {
 	cycles map[kueue.CohortReference]bool
diff --git a/pkg/hierarchy/manager.go b/pkg/hierarchy/manager.go
index 7fdc27c1d..e4d87f756 100644
--- a/pkg/hierarchy/manager.go
+++ b/pkg/hierarchy/manager.go
@@ -176,7 +176,7 @@ func (m *Manager[CQ, C]) resetCycleChecker() {
 	m.CycleChecker = CycleChecker{make(map[kueue.CohortReference]bool, len(m.cohorts))}
 }
 
-// A special constructor for using in tests
+// NewManagerForTest is a special constructor for using in tests
 func NewManagerForTest[CQ clusterQueueNode[C], C cohortNode[CQ, C]](cohorts map[kueue.CohortReference]C, clusterQueues map[kueue.ClusterQueueReference]CQ) Manager[CQ, C] {
 	return Manager[CQ, C]{
 		cohorts:       cohorts,
diff --git a/pkg/scheduler/preemption/fairsharing/strategy.go b/pkg/scheduler/preemption/fairsharing/strategy.go
new file mode 100644
index 000000000..df413792c
--- /dev/null
+++ b/pkg/scheduler/preemption/fairsharing/strategy.go
@@ -0,0 +1,43 @@
+/*
+Copyright The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package fairsharing
+
+// PreemptorNewShare is the DominantResourceShare of the Preemptor
+// after the incoming workload's usage has been added. It is used for
+// both rules S2-a and S2-b
+type PreemptorNewShare int
+
+// TargetNewShare is the DominantResourceShare of the Preemptee after
+// its preempted workload's usage has been removed. It is used for
+// rule S2-a.
+type TargetNewShare int
+
+// TargetOldShare is the DominantResourceShare of the Preemptee before
+// its workload has been removed. It is used for rule S2-b.
+type TargetOldShare int
+
+type Strategy func(PreemptorNewShare, TargetOldShare, TargetNewShare) bool
+
+// LessThanOrEqualToFinalShare implements Rule S2-a in https://sigs.k8s.io/kueue/keps/1714-fair-sharing#choosing-workloads-from-clusterqueues-for-preemption
+func LessThanOrEqualToFinalShare(preemptorNewShare PreemptorNewShare, _ TargetOldShare, targetNewShare TargetNewShare) bool {
+	return int(preemptorNewShare) <= int(targetNewShare)
+}
+
+// LessThanInitialShare implements rule S2-b in https://sigs.k8s.io/kueue/keps/1714-fair-sharing#choosing-workloads-from-clusterqueues-for-preemption
+func LessThanInitialShare(preemptorNewShare PreemptorNewShare, targetOldShare TargetOldShare, _ TargetNewShare) bool {
+	return int(preemptorNewShare) < int(targetOldShare)
+}
diff --git a/pkg/scheduler/preemption/preemption.go b/pkg/scheduler/preemption/preemption.go
index 84d51cdb6..68f180f0c 100644
--- a/pkg/scheduler/preemption/preemption.go
+++ b/pkg/scheduler/preemption/preemption.go
@@ -42,6 +42,7 @@ import (
 	"sigs.k8s.io/kueue/pkg/metrics"
 	"sigs.k8s.io/kueue/pkg/resources"
 	"sigs.k8s.io/kueue/pkg/scheduler/flavorassigner"
+	"sigs.k8s.io/kueue/pkg/scheduler/preemption/fairsharing"
 	"sigs.k8s.io/kueue/pkg/util/heap"
 	"sigs.k8s.io/kueue/pkg/util/priority"
 	"sigs.k8s.io/kueue/pkg/util/routine"
@@ -58,7 +59,7 @@ type Preemptor struct {
 
 	workloadOrdering  workload.Ordering
 	enableFairSharing bool
-	fsStrategies      []fsStrategy
+	fsStrategies      []fairsharing.Strategy
 
 	// stubs
 	applyPreemption func(ctx context.Context, w *kueue.Workload, reason, message string) error
@@ -69,7 +70,7 @@ type preemptionCtx struct {
 	preemptor         workload.Info
 	preemptorCQ       *cache.ClusterQueueSnapshot
 	snapshot          *cache.Snapshot
-	requests          resources.FlavorResourceQuantities
+	workloadUsage     workload.Usage
 	tasRequests       cache.WorkloadTASRequests
 	frsNeedPreemption sets.Set[resources.FlavorResource]
 }
@@ -132,9 +133,12 @@ func (p *Preemptor) GetTargets(log logr.Logger, wl workload.Info, assignment fla
 		preemptor:         wl,
 		preemptorCQ:       cq,
 		snapshot:          snapshot,
-		requests:          assignment.TotalRequestsFor(&wl),
 		tasRequests:       tasRequests,
 		frsNeedPreemption: flavorResourcesNeedPreemption(assignment),
+		workloadUsage: workload.Usage{
+			Quota: assignment.TotalRequestsFor(&wl),
+			TAS:   wl.TASUsage(),
+		},
 	})
 }
 
@@ -144,6 +148,9 @@ func (p *Preemptor) getTargets(preemptionCtx *preemptionCtx) []*Target {
 		return nil
 	}
 	sort.Slice(candidates, candidatesOrdering(candidates, preemptionCtx.preemptorCQ.Name, p.clock.Now()))
+	if p.enableFairSharing {
+		return fairPreemptions(preemptionCtx, candidates, p.fsStrategies)
+	}
 
 	sameQueueCandidates := candidatesOnlyFromQueue(candidates, preemptionCtx.preemptorCQ.Name)
 
@@ -158,9 +165,6 @@ func (p *Preemptor) getTargets(preemptionCtx *preemptionCtx) []*Target {
 		return minimalPreemptions(preemptionCtx, candidates, true, nil)
 	}
 
-	if p.enableFairSharing {
-		return fairPreemptions(preemptionCtx, candidates, p.fsStrategies)
-	}
 	// There is a potential of preemption of workloads from the other queue in the
 	// cohort. We proceed with borrowing only if the dedicated policy
 	// (borrowWithinCohort) is enabled. This ensures the preempted workloads
@@ -344,32 +348,20 @@ func restoreSnapshot(snapshot *cache.Snapshot, targets []*Target) {
 	}
 }
 
-type fsStrategy func(preemptorNewShare, preempteeOldShare, preempteeNewShare int) bool
-
-// lessThanOrEqualToFinalShare implements Rule S2-a in https://sigs.k8s.io/kueue/keps/1714-fair-sharing#choosing-workloads-from-clusterqueues-for-preemption
-func lessThanOrEqualToFinalShare(preemptorNewShare, _, preempteeNewShare int) bool {
-	return preemptorNewShare <= preempteeNewShare
-}
-
-// lessThanInitialShare implements rule S2-b in https://sigs.k8s.io/kueue/keps/1714-fair-sharing#choosing-workloads-from-clusterqueues-for-preemption
-func lessThanInitialShare(preemptorNewShare, preempteeOldShare, _ int) bool {
-	return preemptorNewShare < preempteeOldShare
-}
-
 // parseStrategies converts an array of strategies into the functions to the used by the algorithm.
 // This function takes advantage of the properties of the preemption algorithm and the strategies.
 // The number of functions returned might not match the input slice.
-func parseStrategies(s []config.PreemptionStrategy) []fsStrategy {
+func parseStrategies(s []config.PreemptionStrategy) []fairsharing.Strategy {
 	if len(s) == 0 {
-		return []fsStrategy{lessThanOrEqualToFinalShare, lessThanInitialShare}
+		return []fairsharing.Strategy{fairsharing.LessThanOrEqualToFinalShare, fairsharing.LessThanInitialShare}
 	}
-	strategies := make([]fsStrategy, len(s))
+	strategies := make([]fairsharing.Strategy, len(s))
 	for i, strategy := range s {
 		switch strategy {
 		case config.LessThanOrEqualToFinalShare:
-			strategies[i] = lessThanOrEqualToFinalShare
+			strategies[i] = fairsharing.LessThanOrEqualToFinalShare
 		case config.LessThanInitialShare:
-			strategies[i] = lessThanInitialShare
+			strategies[i] = fairsharing.LessThanInitialShare
 		}
 	}
 	return strategies
@@ -378,10 +370,9 @@ func parseStrategies(s []config.PreemptionStrategy) []fsStrategy {
 // runFirstFsStrategy runs the first configured FairSharing strategy,
 // and returns (fits, targets, retryCandidates) retryCandidates may be
 // used if rule S2-b is configured.
-func runFirstFsStrategy(preemptionCtx *preemptionCtx, candidates []*workload.Info, strategy fsStrategy) (bool, []*Target, []*workload.Info) {
-	requests := preemptionCtx.requests
+func runFirstFsStrategy(preemptionCtx *preemptionCtx, candidates []*workload.Info, strategy fairsharing.Strategy) (bool, []*Target, []*workload.Info) {
 	cqHeap := cqHeapFromCandidates(candidates, false, preemptionCtx.snapshot)
-	newNominatedShareValue := preemptionCtx.preemptorCQ.DominantResourceShareWith(requests)
+	preemptorNewShare := fairsharing.PreemptorNewShare(preemptionCtx.preemptorCQ.DominantResourceShare())
 	var targets []*Target
 	var retryCandidates []*workload.Info
 	for cqHeap.Len() > 0 {
@@ -394,21 +385,21 @@ func runFirstFsStrategy(preemptionCtx *preemptionCtx, candidates []*workload.Inf
 				WorkloadInfo: candWl,
 				Reason:       kueue.InClusterQueueReason,
 			})
-			if workloadFits(preemptionCtx, true) {
+			if workloadFitsForFairSharing(preemptionCtx) {
 				return true, targets, nil
 			}
-			newNominatedShareValue = preemptionCtx.preemptorCQ.DominantResourceShareWith(requests)
+			preemptorNewShare = fairsharing.PreemptorNewShare(preemptionCtx.preemptorCQ.DominantResourceShare())
 			candCQ.workloads = candCQ.workloads[1:]
 			if len(candCQ.workloads) > 0 {
-				candCQ.share = candCQ.cq.DominantResourceShare()
+				candCQ.share = fairsharing.TargetOldShare(candCQ.cq.DominantResourceShare())
 				cqHeap.PushIfNotPresent(candCQ)
 			}
 			continue
 		}
 
 		for i, candWl := range candCQ.workloads {
-			newCandShareVal := candCQ.cq.DominantResourceShareWithout(candWl.FlavorResourceUsage())
-			if strategy(newNominatedShareValue, candCQ.share, newCandShareVal) {
+			targetNewShare := fairsharing.TargetNewShare(candCQ.cq.DominantResourceShareWithout(candWl.FlavorResourceUsage()))
+			if strategy(preemptorNewShare, candCQ.share, targetNewShare) {
 				preemptionCtx.snapshot.RemoveWorkload(candWl)
 				reason := kueue.InCohortFairSharingReason
 
@@ -416,12 +407,12 @@ func runFirstFsStrategy(preemptionCtx *preemptionCtx, candidates []*workload.Inf
 					WorkloadInfo: candWl,
 					Reason:       reason,
 				})
-				if workloadFits(preemptionCtx, true) {
+				if workloadFitsForFairSharing(preemptionCtx) {
 					return true, targets, nil
 				}
 				candCQ.workloads = candCQ.workloads[i+1:]
 				if len(candCQ.workloads) > 0 && cqIsBorrowing(candCQ.cq, preemptionCtx.frsNeedPreemption) {
-					candCQ.share = newCandShareVal
+					candCQ.share = fairsharing.TargetOldShare(candCQ.cq.DominantResourceShare())
 					cqHeap.PushIfNotPresent(candCQ)
 				}
 				// Might need to pick a different CQ due to changing values.
@@ -438,12 +429,12 @@ func runFirstFsStrategy(preemptionCtx *preemptionCtx, candidates []*workload.Inf
 // (fits, targets).
 func runSecondFsStrategy(retryCandidates []*workload.Info, preemptionCtx *preemptionCtx, targets []*Target) (bool, []*Target) {
 	cqHeap := cqHeapFromCandidates(retryCandidates, true, preemptionCtx.snapshot)
-	newNominatedShareValue := preemptionCtx.preemptorCQ.DominantResourceShareWith(preemptionCtx.requests)
+	preemptorNewShare := fairsharing.PreemptorNewShare(preemptionCtx.preemptorCQ.DominantResourceShare())
 	for cqHeap.Len() > 0 {
 		candCQ := cqHeap.Pop()
 		// Due to API validation, we can only reach here if the second strategy is LessThanInitialShare,
 		// in which case the last parameter for the strategy function is irrelevant.
-		if lessThanInitialShare(newNominatedShareValue, candCQ.share, 0) {
+		if fairsharing.LessThanInitialShare(preemptorNewShare, candCQ.share, 0) {
 			// The criteria doesn't depend on the preempted workload, so just preempt the first candidate.
 			candWl := candCQ.workloads[0]
 			preemptionCtx.snapshot.RemoveWorkload(candWl)
@@ -451,7 +442,7 @@ func runSecondFsStrategy(retryCandidates []*workload.Info, preemptionCtx *preemp
 				WorkloadInfo: candWl,
 				Reason:       kueue.InCohortFairSharingReason,
 			})
-			if workloadFits(preemptionCtx, true) {
+			if workloadFitsForFairSharing(preemptionCtx) {
 				return true, targets
 			}
 			// No requeueing because there doesn't seem to be an scenario where
@@ -461,16 +452,20 @@ func runSecondFsStrategy(retryCandidates []*workload.Info, preemptionCtx *preemp
 	return false, targets
 }
 
-func fairPreemptions(preemptionCtx *preemptionCtx, candidates []*workload.Info, strategies []fsStrategy) []*Target {
+func fairPreemptions(preemptionCtx *preemptionCtx, candidates []*workload.Info, strategies []fairsharing.Strategy) []*Target {
 	if logV := preemptionCtx.log.V(5); logV.Enabled() {
 		logV.Info("Simulating fair preemption", "candidates", workload.References(candidates), "resourcesRequiringPreemption", preemptionCtx.frsNeedPreemption.UnsortedList(), "preemptingWorkload", klog.KObj(preemptionCtx.preemptor.Obj))
 	}
 
+	// DRS values must include incoming workload.
+	revertSimulation := preemptionCtx.preemptorCQ.SimulateUsageAddition(preemptionCtx.workloadUsage)
+
 	fits, targets, retryCandidates := runFirstFsStrategy(preemptionCtx, candidates, strategies[0])
 	if !fits && len(strategies) > 1 {
 		fits, targets = runSecondFsStrategy(retryCandidates, preemptionCtx, targets)
 	}
 
+	revertSimulation()
 	if !fits {
 		restoreSnapshot(preemptionCtx.snapshot, targets)
 		return nil
@@ -483,7 +478,7 @@ func fairPreemptions(preemptionCtx *preemptionCtx, candidates []*workload.Info,
 type candidateCQ struct {
 	cq        *cache.ClusterQueueSnapshot
 	workloads []*workload.Info
-	share     int
+	share     fairsharing.TargetOldShare
 }
 
 func cqHeapFromCandidates(candidates []*workload.Info, firstOnly bool, snapshot *cache.Snapshot) *heap.Heap[candidateCQ] {
@@ -502,7 +497,7 @@ func cqHeapFromCandidates(candidates []*workload.Info, firstOnly bool, snapshot
 			share := cq.DominantResourceShare()
 			candCQ = &candidateCQ{
 				cq:        cq,
-				share:     share,
+				share:     fairsharing.TargetOldShare(share),
 				workloads: []*workload.Info{cand},
 			}
 			cqHeap.PushOrUpdate(candCQ)
@@ -601,7 +596,7 @@ func workloadUsesResources(wl *workload.Info, frsNeedPreemption sets.Set[resourc
 // requestable resources and simulated usage of the ClusterQueue and its cohort,
 // if it belongs to one.
 func workloadFits(preemptionCtx *preemptionCtx, allowBorrowing bool) bool {
-	for fr, v := range preemptionCtx.requests {
+	for fr, v := range preemptionCtx.workloadUsage.Quota {
 		if !allowBorrowing && preemptionCtx.preemptorCQ.BorrowingWith(fr, v) {
 			return false
 		}
@@ -613,6 +608,17 @@ func workloadFits(preemptionCtx *preemptionCtx, allowBorrowing bool) bool {
 	return tasResult.Failure() == nil
 }
 
+// workloadFitsForFairSharing is a lightweight wrapper around
+// workloadFits, as we need to remove, and then add back, the usage of
+// the incoming workload, as FairSharing adds this usage at the start
+// of processing for accurate DominantResourceShare calculations.
+func workloadFitsForFairSharing(preemptionCtx *preemptionCtx) bool {
+	revertSimulation := preemptionCtx.preemptorCQ.SimulateUsageRemoval(preemptionCtx.workloadUsage)
+	res := workloadFits(preemptionCtx, true)
+	revertSimulation()
+	return res
+}
+
 func queueUnderNominalInResourcesNeedingPreemption(preemptionCtx *preemptionCtx) bool {
 	for fr := range preemptionCtx.frsNeedPreemption {
 		if preemptionCtx.preemptorCQ.ResourceNode.Usage[fr] >= preemptionCtx.preemptorCQ.QuotaFor(fr).Nominal {
diff --git a/pkg/scheduler/preemption/preemption_oracle.go b/pkg/scheduler/preemption/preemption_oracle.go
index 7d03b4747..4e0b17542 100644
--- a/pkg/scheduler/preemption/preemption_oracle.go
+++ b/pkg/scheduler/preemption/preemption_oracle.go
@@ -47,7 +47,7 @@ func (p *PreemptionOracle) IsReclaimPossible(log logr.Logger, cq *cache.ClusterQ
 		preemptorCQ:       p.snapshot.ClusterQueue(wl.ClusterQueue),
 		snapshot:          p.snapshot,
 		frsNeedPreemption: sets.New(fr),
-		requests:          resources.FlavorResourceQuantities{fr: quantity},
+		workloadUsage:     workload.Usage{Quota: resources.FlavorResourceQuantities{fr: quantity}},
 	}) {
 		if candidate.WorkloadInfo.ClusterQueue == cq.Name {
 			return false
diff --git a/pkg/scheduler/scheduler.go b/pkg/scheduler/scheduler.go
index 906f634fc..fe11884ae 100644
--- a/pkg/scheduler/scheduler.go
+++ b/pkg/scheduler/scheduler.go
@@ -374,7 +374,7 @@ func fits(cq *cache.ClusterQueueSnapshot, usage *workload.Usage, preemptedWorklo
 	for _, target := range newTargets {
 		workloads = append(workloads, target.WorkloadInfo)
 	}
-	revertUsage := cq.SimulateUsageRemoval(workloads)
+	revertUsage := cq.SimulateWorkloadRemoval(workloads)
 	defer revertUsage()
 	return cq.Fits(*usage)
 }
@@ -468,7 +468,7 @@ func updateAssignmentForTAS(cq *cache.ClusterQueueSnapshot, wl *workload.Info, a
 			for _, target := range targets {
 				targetWorkloads = append(targetWorkloads, target.WorkloadInfo)
 			}
-			revertUsage := cq.SimulateUsageRemoval(targetWorkloads)
+			revertUsage := cq.SimulateWorkloadRemoval(targetWorkloads)
 			tasResult = cq.FindTopologyAssignmentsForWorkload(tasRequests, false)
 			revertUsage()
 		} else {
diff --git a/site/OWNERS b/site/OWNERS
index dfa91ceb6..5dbff6270 100644
--- a/site/OWNERS
+++ b/site/OWNERS
@@ -2,3 +2,7 @@
 
 approvers:
 - moficodes
+
+reviewers:
+- kannon92
+
diff --git a/site/content/en/docs/contribution guidelines/_index.md b/site/content/en/docs/contribution_guidelines/_index.md
similarity index 96%
rename from site/content/en/docs/contribution guidelines/_index.md
rename to site/content/en/docs/contribution_guidelines/_index.md
index 7ecbf7344..8da57fe93 100644
--- a/site/content/en/docs/contribution guidelines/_index.md	
+++ b/site/content/en/docs/contribution_guidelines/_index.md
@@ -13,7 +13,6 @@ _As contributors and maintainers of this project, and in the interest of fosteri
 ## Getting Started
 
 We have full documentation on how to get started contributing here:
-
 <!---
 If your repo has certain guidelines for contribution, put them here ahead of the general k8s resources
 -->
@@ -21,6 +20,7 @@ If your repo has certain guidelines for contribution, put them here ahead of the
 - [Contributor License Agreement](https://git.k8s.io/community/CLA.md) Kubernetes projects require that you sign a Contributor License Agreement (CLA) before we can accept your pull requests
 - [Kubernetes Contributor Guide](https://git.k8s.io/community/contributors/guide) - Main contributor documentation, or you can just jump directly to the [contributing section](https://git.k8s.io/community/contributors/guide#contributing)
 - [Contributor Cheat Sheet](https://git.k8s.io/community/contributors/guide/contributor-cheatsheet) - Common resources for existing developers
+- [Running and debugging tests](/docs/contribution_guidelines/testing.md)
 
 ## Mentorship
 
diff --git a/site/content/en/docs/contribution_guidelines/testing.md b/site/content/en/docs/contribution_guidelines/testing.md
new file mode 100644
index 000000000..b231ddb04
--- /dev/null
+++ b/site/content/en/docs/contribution_guidelines/testing.md
@@ -0,0 +1,185 @@
+---
+title: "Running and debugging tests"
+linkTitle: "Running tests"
+weight: 25
+description: >
+  Running and debugging tests
+---
+
+## Running presubmission verification tests
+```shell
+make verify
+```
+
+## Running unit tests
+To run all unit tests:
+```shell
+make test
+```
+
+To run unit tests for webhooks:
+```shell
+go test ./pkg/webhooks
+```
+To run tests that match `TestValidateClusterQueue` regular expression [ref](https://pkg.go.dev/cmd/go#hdr-Testing_flags):
+```shell
+go test ./pkg/webhooks -run TestValidateClusterQueue
+```
+
+### Running unit tests with race detection
+
+Use `-race` to enable Go's built-in race detector:
+```shell
+go test ./pkg/scheduler/preemption/ -race
+```
+
+### Running unit tests with stress
+
+To run unit tests in a loop and collect failures:
+```shell
+# install go stress
+go install golang.org/x/tools/cmd/stress@latest
+# compile tests (you can add -race for race detection)
+go test ./pkg/scheduler/preemption/ -c
+# it loops and reports failures
+stress ./preemption.test -test.run TestPreemption
+```
+
+## Running integration tests
+
+```shell
+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-multikueue-e2e
+```
+
+You can also change `kind` version by modifying `E2E_KIND_VERSION` variable:
+```shell
+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).
+
+## 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.
+Now you will have `run test | debug test` text buttons above lines like
+```go
+func TestValidateClusterQueue(t *testing.T) {
+```
+You can click on the `debug test` to debug a specific test.
+
+For integration tests, an additional step is needed.  In settings.json, you need to add two variables inside `go.testEnvVars`:
+- Run `ENVTEST_K8S_VERSION=1.32 make envtest && ./bin/setup-envtest use $ENVTEST_K8S_VERSION -p path` and assign the path to the `KUBEBUILDER_ASSETS` variable
+- Set `KUEUE_BIN` to the `bin` directory within your cloned Kueue repository
+```json
+"go.testEnvVars": {
+    "KUBEBUILDER_ASSETS": "<path from output above>",
+    "KUEUE_BIN": "<path-to-your-kueue-folder>/bin",
+  },
+```
+
+For e2e tests, you can also use [Ginkgo Test Explorer](https://marketplace.visualstudio.com/items?itemName=joselitofilho.ginkgotestexplorer).  You need to add the following variables to settings.json:
+```json
+ "ginkgotestexplorer.testEnvVars": {
+        "KIND_CLUSTER_NAME": "kind",
+        "WORKER1_KIND_CLUSTER_NAME": "kind-worker1",
+        "MANAGER_KIND_CLUSTER_NAME": "kind-manager",
+        "WORKER2_KIND_CLUSTER_NAME": "kind-worker2",
+        "KIND": "<your_kueue_path>/bin/kind",
+    },
+```
+and then you can use GUI of the Ginkgo Test Explorer to run individual tests, provided you started kind clanter (see [here](#attaching-e2e-tests-to-an-existing-kind-cluster) for the instructions).
+
+## Attaching e2e tests to an existing kind cluster
+You can use the following approach to start up a kind cluster and then run e2e tests from commandline or VSCode, attaching them to the existing cluster.  For example, suppose you want to test some of the multikueue-e2e tests. Comment the last line of the `hack/multikueue-e2e-test.sh` and add `read -p "run your tests now"` instead:
+```shell
+#$GINKGO $GINKGO_ARGS --junit-report=junit.xml --json-report=e2e.json --output-dir="$ARTIFACTS" -v ./test/e2e/multikueue/...
+read -p "run your tests now"
+```
+Then, run `make kind-image-build test-multikueue-e2e` and wait for the `"run your tests now"` to appear.  The cluster is ready, and now you can run tests from another terminal:
+```shell
+<your_kueue_path>/bin/ginkgo --json-report ./ginkgo.report -focus "MultiKueue when Creating a multikueue admission check Should run a jobSet on worker if admitted" -r
+```
+or from VSCode.
+
+## Running subset of integration or e2e tests
+### Use Ginkgo --focus arg
+```shell
+GINKGO_ARGS="--focus=Scheduler" make test-integration
+GINKGO_ARGS="--focus=Creating a Pod requesting TAS" make test-e2e
+```
+### Use ginkgo.FIt
+If you want to focus on specific tests, you can change
+`ginkgo.It` to `ginkgo.FIt` for these tests.
+For more details, see [here](https://onsi.github.io/ginkgo/#focused-specs).
+Then the other tests will be skipped.
+For example, you can change
+```go
+ginkgo.It("Should place pods based on the ranks-ordering", func() {
+```
+to
+```go
+ginkgo.FIt("Should place pods based on the ranks-ordering", func() {
+```
+and then run
+```shell
+# build and pull image
+make test-tas-e2e
+```
+to test a particular TAS e2e test.
+
+### Use INTEGRATION_TARGET
+```shell
+INTEGRATION_TARGET='test/integration/singlecluster/scheduler' make test-integration
+```
+
+## Flaky integration/e2e tests
+You can use --until-it-fails or --repeat=N arguments to Ginkgo to run tests repeatedly, such as:
+```shell
+GINKGO_ARGS="--until-it-fails" make test-integration
+GINKGO_ARGS="--repeat=10" make test-e2e
+```
+See more [here](https://onsi.github.io/ginkgo/#repeating-spec-runs-and-managing-flaky-specs)
+
+### Adding stress
+You can run [stress](https://github.com/resurrecting-open-source-projects/stress) tool to increase CPU load during tests.  For example, if you're on Debian-based Linux:
+```shell
+# install stress:
+sudo apt install stress
+# run stress alongside tests
+/usr/bin/stress --cpu 80
+```
+
+### Analyzing logs
+Kueue runs as a regular pod on a worker node, and in e2e tests there are 2 replicas running.  The Kueue logs are located in `kind-worker/pods/kueue-system_kueue-controller-manager*/manager` and `kind-worker2/pods/kueue-system_kueue-controller-manager*/manager` folders.
+
+For each log message you can from which file and line the message is coming from:
+```log
+2025-02-03T15:51:51.502425029Z stderr F 2025-02-03T15:51:51.502117824Z	LEVEL(-2)	cluster-queue-reconciler	core/clusterqueue_controller.go:341	ClusterQueue update event	{"clusterQueue": {"name":"cluster-queue"}}
+```
+Here, it's `core/clusterqueue_controller.go:341`.
+
+### See also
+- [Kubernetes testing guide](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-testing/testing.md)
+- [Integration Testing in Kubernetes](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-testing/integration-tests.md)
+- [End-to-End Testing in Kubernetes](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-testing/e2e-tests.md)
+- [Flaky Tests in Kubernetes](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-testing/flaky-tests.md)
diff --git a/site/content/en/docs/reference/kueue-config.v1beta1.md b/site/content/en/docs/reference/kueue-config.v1beta1.md
index 02230cfef..ec9c395b0 100644
--- a/site/content/en/docs/reference/kueue-config.v1beta1.md
+++ b/site/content/en/docs/reference/kueue-config.v1beta1.md
@@ -579,9 +579,16 @@ underlying job are changed.</p>
 <code>bool</code>
 </td>
 <td>
-   <p>Enable controls whether to enable internal cert management or not.
-Defaults to true. If you want to use a third-party management, e.g. cert-manager,
-set it to false. See the user guide for more information.</p>
+   <p>Enable controls the use of internal cert management for the webhook
+and metrics endpoints.
+When enabled Kueue is using libraries to generate and
+self-sign the certificates.
+When disabled, you need to provide the certificates for
+the webhooks and metrics through a third party certificate
+This secret is mounted to the kueue controller manager pod. The mount
+path for webhooks is /tmp/k8s-webhook-server/serving-certs, whereas for
+metrics endpoint the expected path is <code>/etc/kueue/metrics/certs</code>.
+The keys and certs are named tls.key and tls.crt.</p>
 </td>
 </tr>
 <tr><td><code>webhookServiceName</code> <B>[Required]</B><br/>
diff --git a/site/content/en/docs/reference/kueue.v1beta1.md b/site/content/en/docs/reference/kueue.v1beta1.md
index b922e3876..d9975242a 100644
--- a/site/content/en/docs/reference/kueue.v1beta1.md
+++ b/site/content/en/docs/reference/kueue.v1beta1.md
@@ -1832,6 +1832,15 @@ indicated by the <code>kueue.x-k8s.io/podset-preferred-topology</code> PodSet
 annotation.</p>
 </td>
 </tr>
+<tr><td><code>unconstrained</code><br/>
+<code>bool</code>
+</td>
+<td>
+   <p>unconstrained indicates that Kueue has the freedom to schedule the PodSet within
+the entire available capacity, without constraints on the compactness of the placement.
+This is indicated by the <code>kueue.x-k8s.io/podset-unconstrained-topology</code> PodSet annotation.</p>
+</td>
+</tr>
 <tr><td><code>podIndexLabel</code> <B>[Required]</B><br/>
 <code>string</code>
 </td>



Test patch:
diff --git a/pkg/cache/tas_cache_test.go b/pkg/cache/tas_cache_test.go
index 3918717e6..4d67498d1 100644
--- a/pkg/cache/tas_cache_test.go
+++ b/pkg/cache/tas_cache_test.go
@@ -23,6 +23,7 @@ import (
 	"github.com/google/go-cmp/cmp"
 	corev1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/api/resource"
+	"k8s.io/component-base/featuregate"
 	"k8s.io/utils/ptr"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
@@ -115,6 +116,69 @@ func TestFindTopologyAssignment(t *testing.T) {
 			Ready().
 			Obj(),
 	}
+	//nolint:dupword // suppress duplicate r1 word
+	//       b1           b2
+	//       |             |
+	//       r1           r1
+	//     /  |  \       /  \
+	//   x1  x2  x3     x4  x5
+	scatteredNodes := []corev1.Node{
+		*testingnode.MakeNode("b1-r1-x1").
+			Label(tasBlockLabel, "b1").
+			Label(tasRackLabel, "r1").
+			Label(corev1.LabelHostname, "x1").
+			StatusAllocatable(corev1.ResourceList{
+				corev1.ResourceCPU:    resource.MustParse("4"),
+				corev1.ResourceMemory: resource.MustParse("1Gi"),
+				corev1.ResourcePods:   resource.MustParse("10"),
+			}).
+			Ready().
+			Obj(),
+		*testingnode.MakeNode("b1-r1-x2").
+			Label(tasBlockLabel, "b1").
+			Label(tasRackLabel, "r1").
+			Label(corev1.LabelHostname, "x2").
+			StatusAllocatable(corev1.ResourceList{
+				corev1.ResourceCPU:    resource.MustParse("1"),
+				corev1.ResourceMemory: resource.MustParse("1Gi"),
+				corev1.ResourcePods:   resource.MustParse("10"),
+			}).
+			Ready().
+			Obj(),
+		*testingnode.MakeNode("b1-r1-x3").
+			Label(tasBlockLabel, "b1").
+			Label(tasRackLabel, "r1").
+			Label(corev1.LabelHostname, "x3").
+			StatusAllocatable(corev1.ResourceList{
+				corev1.ResourceCPU:    resource.MustParse("1"),
+				corev1.ResourceMemory: resource.MustParse("1Gi"),
+				corev1.ResourcePods:   resource.MustParse("10"),
+			}).
+			Ready().
+			Obj(),
+		*testingnode.MakeNode("b2-r1-x4").
+			Label(tasBlockLabel, "b2").
+			Label(tasRackLabel, "r1").
+			Label(corev1.LabelHostname, "x4").
+			StatusAllocatable(corev1.ResourceList{
+				corev1.ResourceCPU:    resource.MustParse("2"),
+				corev1.ResourceMemory: resource.MustParse("1Gi"),
+				corev1.ResourcePods:   resource.MustParse("10"),
+			}).
+			Ready().
+			Obj(),
+		*testingnode.MakeNode("b2-r1-x5").
+			Label(tasBlockLabel, "b2").
+			Label(tasRackLabel, "r1").
+			Label(corev1.LabelHostname, "x5").
+			StatusAllocatable(corev1.ResourceList{
+				corev1.ResourceCPU:    resource.MustParse("1"),
+				corev1.ResourceMemory: resource.MustParse("1Gi"),
+				corev1.ResourcePods:   resource.MustParse("10"),
+			}).
+			Ready().
+			Obj(),
+	}
 	defaultOneLevel := []string{
 		corev1.LabelHostname,
 	}
@@ -226,17 +290,17 @@ func TestFindTopologyAssignment(t *testing.T) {
 
 	cases := map[string]struct {
 		// TODO: remove after dropping the TASMostFreeCapacity feature gate
-		enableTASMostFreeCapacity bool
-		wantReason                string
-		topologyRequest           kueue.PodSetTopologyRequest
-		levels                    []string
-		nodeLabels                map[string]string
-		nodes                     []corev1.Node
-		pods                      []corev1.Pod
-		requests                  resources.Requests
-		count                     int32
-		tolerations               []corev1.Toleration
-		wantAssignment            *kueue.TopologyAssignment
+		enableFeatureGates []featuregate.Feature
+		wantReason         string
+		topologyRequest    *kueue.PodSetTopologyRequest
+		levels             []string
+		nodeLabels         map[string]string
+		nodes              []corev1.Node
+		pods               []corev1.Pod
+		requests           resources.Requests
+		count              int32
+		tolerations        []corev1.Toleration
+		wantAssignment     *kueue.TopologyAssignment
 	}{
 		// TODO: remove suffixes MostFreeCapacity/BestFit after dropping the TASMostFreeCapacity feature gate
 		"minimize the number of used racks before optimizing the number of nodes; MostFreeCapacity": {
@@ -311,7 +375,7 @@ func TestFindTopologyAssignment(t *testing.T) {
 					Ready().
 					Obj(),
 			},
-			topologyRequest: kueue.PodSetTopologyRequest{
+			topologyRequest: &kueue.PodSetTopologyRequest{
 				Required: ptr.To(tasBlockLabel),
 			},
 			levels: defaultThreeLevels,
@@ -348,11 +412,337 @@ func TestFindTopologyAssignment(t *testing.T) {
 					},
 				},
 			},
-			enableTASMostFreeCapacity: true,
+			enableFeatureGates: []featuregate.Feature{features.TASProfileMostFreeCapacity},
+		},
+		"minimize resource fragmentation; LeastFreeCapacityFit": {
+			//        b1
+			//         |
+			//        r1
+			//    /    |    \
+			// x1:2, x2:1, x3:1
+			//
+			nodes: []corev1.Node{
+				*testingnode.MakeNode("b1-r1-x1").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r1").
+					Label(corev1.LabelHostname, "x1").
+					StatusAllocatable(corev1.ResourceList{
+						corev1.ResourceCPU:  resource.MustParse("2"),
+						corev1.ResourcePods: resource.MustParse("10"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b1-r1-x2").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r1").
+					Label(corev1.LabelHostname, "x2").
+					StatusAllocatable(corev1.ResourceList{
+						corev1.ResourceCPU:  resource.MustParse("1"),
+						corev1.ResourcePods: resource.MustParse("10"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b1-r1-x3").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r1").
+					Label(corev1.LabelHostname, "x3").
+					StatusAllocatable(corev1.ResourceList{
+						corev1.ResourceCPU:  resource.MustParse("1"),
+						corev1.ResourcePods: resource.MustParse("10"),
+					}).
+					Ready().
+					Obj(),
+			},
+			topologyRequest: &kueue.PodSetTopologyRequest{
+				Required: ptr.To(tasBlockLabel),
+			},
+			levels: defaultThreeLevels,
+			requests: resources.Requests{
+				corev1.ResourceCPU: 1000,
+			},
+			count: 2,
+			wantAssignment: &kueue.TopologyAssignment{
+				Levels: defaultOneLevel,
+				Domains: []kueue.TopologyDomainAssignment{
+					{
+						Count: 1,
+						Values: []string{
+							"x3",
+						},
+					},
+					{
+						Count: 1,
+						Values: []string{
+							"x2",
+						},
+					},
+				},
+			},
+			enableFeatureGates: []featuregate.Feature{features.TASProfileLeastFreeCapacity},
+		},
+		"choose the node that can accommodate all Pods": {
+			//        b1
+			//         |
+			//        r1
+			//    /    |    \
+			// x1:2, x2:1, x3:1
+			nodes: []corev1.Node{
+				*testingnode.MakeNode("b1-r1-x1").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r1").
+					Label(corev1.LabelHostname, "x1").
+					StatusAllocatable(corev1.ResourceList{
+						corev1.ResourceCPU:  resource.MustParse("2"),
+						corev1.ResourcePods: resource.MustParse("10"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b1-r1-x2").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r1").
+					Label(corev1.LabelHostname, "x2").
+					StatusAllocatable(corev1.ResourceList{
+						corev1.ResourceCPU:  resource.MustParse("1"),
+						corev1.ResourcePods: resource.MustParse("10"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b1-r1-x3").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r1").
+					Label(corev1.LabelHostname, "x3").
+					StatusAllocatable(corev1.ResourceList{
+						corev1.ResourceCPU:  resource.MustParse("1"),
+						corev1.ResourcePods: resource.MustParse("10"),
+					}).
+					Ready().
+					Obj(),
+			},
+			topologyRequest: &kueue.PodSetTopologyRequest{
+				Required: ptr.To(tasBlockLabel),
+			},
+			levels: defaultThreeLevels,
+			requests: resources.Requests{
+				corev1.ResourceCPU: 1000,
+			},
+			count: 2,
+			wantAssignment: &kueue.TopologyAssignment{
+				Levels: defaultOneLevel,
+				Domains: []kueue.TopologyDomainAssignment{
+					{
+						Count: 2,
+						Values: []string{
+							"x1",
+						},
+					},
+				},
+			},
+		},
+		"unconstrained; 2 pods fit into hosts scattered across the whole datacenter even they could fit into single rack; LeastFreeCapacity": {
+			nodes: scatteredNodes,
+			topologyRequest: &kueue.PodSetTopologyRequest{
+				Unconstrained: ptr.To(true),
+			},
+			levels: defaultThreeLevels,
+			requests: resources.Requests{
+				corev1.ResourceCPU: 1000,
+			},
+			count: 2,
+			wantAssignment: &kueue.TopologyAssignment{
+				Levels: defaultOneLevel,
+				Domains: []kueue.TopologyDomainAssignment{
+					{
+						Count: 1,
+						Values: []string{
+							"x3",
+						},
+					},
+					{
+						Count: 1,
+						Values: []string{
+							"x5",
+						},
+					},
+				},
+			},
+			enableFeatureGates: []featuregate.Feature{features.TASProfileLeastFreeCapacity},
+		},
+		"no annotation; implied default to unconstrained; 6 pods fit into hosts scattered across the whole datacenter even they could fit into single rack; BestFit": {
+			nodes:  scatteredNodes,
+			levels: defaultThreeLevels,
+			requests: resources.Requests{
+				corev1.ResourceCPU: 1000,
+			},
+			count: 6,
+			wantAssignment: &kueue.TopologyAssignment{
+				Levels: defaultOneLevel,
+				Domains: []kueue.TopologyDomainAssignment{
+					{
+						Count: 4,
+						Values: []string{
+							"x1",
+						},
+					},
+					{
+						Count: 2,
+						Values: []string{
+							"x4",
+						},
+					},
+				},
+			},
+		},
+		"unconstrained; 6 pods fit into hosts scattered across the whole datacenter even they could fit into single rack; BestFit": {
+			nodes: scatteredNodes,
+			topologyRequest: &kueue.PodSetTopologyRequest{
+				Unconstrained: ptr.To(true),
+			},
+			levels: defaultThreeLevels,
+			requests: resources.Requests{
+				corev1.ResourceCPU: 1000,
+			},
+			count: 6,
+			wantAssignment: &kueue.TopologyAssignment{
+				Levels: defaultOneLevel,
+				Domains: []kueue.TopologyDomainAssignment{
+					{
+						Count: 4,
+						Values: []string{
+							"x1",
+						},
+					},
+					{
+						Count: 2,
+						Values: []string{
+							"x4",
+						},
+					},
+				},
+			},
+		},
+		"unconstrained; 6 pods fit into hosts scattered across the whole datacenter even they could fit into single rack; MostFreeCapacityFit": {
+			nodes: scatteredNodes,
+			topologyRequest: &kueue.PodSetTopologyRequest{
+				Unconstrained: ptr.To(true),
+			},
+			levels: defaultThreeLevels,
+			requests: resources.Requests{
+				corev1.ResourceCPU: 1000,
+			},
+			count: 6,
+			wantAssignment: &kueue.TopologyAssignment{
+				Levels: defaultOneLevel,
+				Domains: []kueue.TopologyDomainAssignment{
+					{
+						Count: 4,
+						Values: []string{
+							"x1",
+						},
+					},
+					{
+						Count: 2,
+						Values: []string{
+							"x4",
+						},
+					},
+				},
+			},
+			enableFeatureGates: []featuregate.Feature{features.TASProfileMostFreeCapacity},
+		},
+		"unconstrained; a single pod fits into each host; BestFit": {
+			nodes: defaultNodes,
+			topologyRequest: &kueue.PodSetTopologyRequest{
+				Unconstrained: ptr.To(true),
+			},
+			levels: defaultThreeLevels,
+			requests: resources.Requests{
+				corev1.ResourceCPU: 1000,
+			},
+			count: 1,
+			wantAssignment: &kueue.TopologyAssignment{
+				Levels: defaultOneLevel,
+				Domains: []kueue.TopologyDomainAssignment{
+					{
+						Count: 1,
+						Values: []string{
+							"x1",
+						},
+					},
+				},
+			},
+		},
+		"unconstrained; a single pod fits into each host; MostFreeCapacity": {
+			nodes: defaultNodes,
+			topologyRequest: &kueue.PodSetTopologyRequest{
+				Unconstrained: ptr.To(true),
+			},
+			levels: defaultThreeLevels,
+			requests: resources.Requests{
+				corev1.ResourceCPU: 1000,
+			},
+			count: 1,
+			wantAssignment: &kueue.TopologyAssignment{
+				Levels: defaultOneLevel,
+				Domains: []kueue.TopologyDomainAssignment{
+					{
+						Count: 1,
+						Values: []string{
+							"x6",
+						},
+					},
+				},
+			},
+			enableFeatureGates: []featuregate.Feature{features.TASProfileMostFreeCapacity},
+		},
+		"unconstrained; a single pod fits into each host; LeastFreeCapacity; TASProfileLeastFreeCapacity": {
+			nodes: defaultNodes,
+			topologyRequest: &kueue.PodSetTopologyRequest{
+				Unconstrained: ptr.To(true),
+			},
+			levels: defaultThreeLevels,
+			requests: resources.Requests{
+				corev1.ResourceCPU: 1000,
+			},
+			count: 1,
+			wantAssignment: &kueue.TopologyAssignment{
+				Levels: defaultOneLevel,
+				Domains: []kueue.TopologyDomainAssignment{
+					{
+						Count: 1,
+						Values: []string{
+							"x5",
+						},
+					},
+				},
+			},
+			enableFeatureGates: []featuregate.Feature{features.TASProfileLeastFreeCapacity},
+		},
+		"unconstrained; a single pod fits into each host; LeastFreeCapacity; TASProfileMixed": {
+			nodes: defaultNodes,
+			topologyRequest: &kueue.PodSetTopologyRequest{
+				Unconstrained: ptr.To(true),
+			},
+			levels: defaultThreeLevels,
+			requests: resources.Requests{
+				corev1.ResourceCPU: 1000,
+			},
+			count: 1,
+			wantAssignment: &kueue.TopologyAssignment{
+				Levels: defaultOneLevel,
+				Domains: []kueue.TopologyDomainAssignment{
+					{
+						Count: 1,
+						Values: []string{
+							"x5",
+						},
+					},
+				},
+			},
+			enableFeatureGates: []featuregate.Feature{features.TASProfileMixed},
 		},
 		"block required; 4 pods fit into one host each; MostFreeCapacity": {
 			nodes: binaryTreesNodes,
-			topologyRequest: kueue.PodSetTopologyRequest{
+			topologyRequest: &kueue.PodSetTopologyRequest{
 				Required: ptr.To(tasBlockLabel),
 			},
 			levels: defaultThreeLevels,
@@ -389,11 +779,11 @@ func TestFindTopologyAssignment(t *testing.T) {
 					},
 				},
 			},
-			enableTASMostFreeCapacity: true,
+			enableFeatureGates: []featuregate.Feature{features.TASProfileMostFreeCapacity},
 		},
 		"block required; 4 pods fit into one host each; BestFit": {
 			nodes: binaryTreesNodes,
-			topologyRequest: kueue.PodSetTopologyRequest{
+			topologyRequest: &kueue.PodSetTopologyRequest{
 				Required: ptr.To(tasBlockLabel),
 			},
 			levels: defaultThreeLevels,
@@ -430,12 +820,11 @@ func TestFindTopologyAssignment(t *testing.T) {
 					},
 				},
 			},
-			enableTASMostFreeCapacity: false,
 		},
 		"host required; single Pod fits in the host; MostFreeCapacity": {
 			// TODO: remove after dropping the TASMostFreeCapacity feature gate
 			nodes: defaultNodes,
-			topologyRequest: kueue.PodSetTopologyRequest{
+			topologyRequest: &kueue.PodSetTopologyRequest{
 				Required: ptr.To(corev1.LabelHostname),
 			},
 			levels: defaultThreeLevels,
@@ -454,11 +843,34 @@ func TestFindTopologyAssignment(t *testing.T) {
 					},
 				},
 			},
-			enableTASMostFreeCapacity: true,
+			enableFeatureGates: []featuregate.Feature{features.TASProfileMostFreeCapacity},
+		},
+		"host required; single Pod fits in the host; LeastFreeCapacityFit": {
+			nodes: defaultNodes,
+			topologyRequest: &kueue.PodSetTopologyRequest{
+				Required: ptr.To(corev1.LabelHostname),
+			},
+			levels: defaultThreeLevels,
+			requests: resources.Requests{
+				corev1.ResourceCPU: 1000,
+			},
+			count: 1,
+			wantAssignment: &kueue.TopologyAssignment{
+				Levels: defaultOneLevel,
+				Domains: []kueue.TopologyDomainAssignment{
+					{
+						Count: 1,
+						Values: []string{
+							"x5",
+						},
+					},
+				},
+			},
+			enableFeatureGates: []featuregate.Feature{features.TASProfileLeastFreeCapacity},
 		},
 		"host required; single Pod fits in the host; BestFit": {
 			nodes: defaultNodes,
-			topologyRequest: kueue.PodSetTopologyRequest{
+			topologyRequest: &kueue.PodSetTopologyRequest{
 				Required: ptr.To(corev1.LabelHostname),
 			},
 			levels: defaultThreeLevels,
@@ -477,12 +889,57 @@ func TestFindTopologyAssignment(t *testing.T) {
 					},
 				},
 			},
-			enableTASMostFreeCapacity: false,
+		},
+		"host required; single Pod fits in the host; BestFit; TASProfileMixed": {
+			nodes: defaultNodes,
+			topologyRequest: &kueue.PodSetTopologyRequest{
+				Required: ptr.To(corev1.LabelHostname),
+			},
+			levels: defaultThreeLevels,
+			requests: resources.Requests{
+				corev1.ResourceCPU: 1000,
+			},
+			count: 1,
+			wantAssignment: &kueue.TopologyAssignment{
+				Levels: defaultOneLevel,
+				Domains: []kueue.TopologyDomainAssignment{
+					{
+						Count: 1,
+						Values: []string{
+							"x1",
+						},
+					},
+				},
+			},
+			enableFeatureGates: []featuregate.Feature{features.TASProfileMixed},
+		},
+		"host preferred; single Pod fits in the host; BestFit; TASProfileMixed": {
+			nodes: defaultNodes,
+			topologyRequest: &kueue.PodSetTopologyRequest{
+				Required: ptr.To(corev1.LabelHostname),
+			},
+			levels: defaultThreeLevels,
+			requests: resources.Requests{
+				corev1.ResourceCPU: 1000,
+			},
+			count: 1,
+			wantAssignment: &kueue.TopologyAssignment{
+				Levels: defaultOneLevel,
+				Domains: []kueue.TopologyDomainAssignment{
+					{
+						Count: 1,
+						Values: []string{
+							"x1",
+						},
+					},
+				},
+			},
+			enableFeatureGates: []featuregate.Feature{features.TASProfileMixed},
 		},
 		"rack required; single Pod fits in a rack; MostFreeCapacity": {
 			// TODO: remove after dropping the TASMostFreeCapacity feature gate
 			nodes: defaultNodes,
-			topologyRequest: kueue.PodSetTopologyRequest{
+			topologyRequest: &kueue.PodSetTopologyRequest{
 				Required: ptr.To(tasRackLabel),
 			},
 			levels: defaultTwoLevels,
@@ -502,11 +959,65 @@ func TestFindTopologyAssignment(t *testing.T) {
 					},
 				},
 			},
-			enableTASMostFreeCapacity: true,
+			enableFeatureGates: []featuregate.Feature{features.TASProfileMostFreeCapacity},
+		},
+		"rack required; single Pod fits in a rack; LeastFreeCapacityFit": {
+			nodes: defaultNodes,
+			topologyRequest: &kueue.PodSetTopologyRequest{
+				Required: ptr.To(tasRackLabel),
+			},
+			levels: defaultThreeLevels,
+			requests: resources.Requests{
+				corev1.ResourceCPU: 1000,
+			},
+			count: 1,
+			wantAssignment: &kueue.TopologyAssignment{
+				Levels: defaultOneLevel,
+				Domains: []kueue.TopologyDomainAssignment{
+					{
+						Count: 1,
+						Values: []string{
+							"x5",
+						},
+					},
+				},
+			},
+			enableFeatureGates: []featuregate.Feature{features.TASProfileLeastFreeCapacity},
+		},
+		"rack preferred; multiple Pods fits in multiple racks; LeastFreeCapacityFit": {
+			nodes: defaultNodes,
+			topologyRequest: &kueue.PodSetTopologyRequest{
+				Preferred: ptr.To(tasRackLabel),
+			},
+			levels: defaultTwoLevels,
+			requests: resources.Requests{
+				corev1.ResourceCPU: 1000,
+			},
+			count: 2,
+			wantAssignment: &kueue.TopologyAssignment{
+				Levels: defaultTwoLevels,
+				Domains: []kueue.TopologyDomainAssignment{
+					{
+						Count: 1,
+						Values: []string{
+							"b2",
+							"r1",
+						},
+					},
+					{
+						Count: 1,
+						Values: []string{
+							"b2",
+							"r2",
+						},
+					},
+				},
+			},
+			enableFeatureGates: []featuregate.Feature{features.TASProfileLeastFreeCapacity},
 		},
 		"rack required; multiple Pods fits in a rack; MostFreeCapacity": {
 			nodes: defaultNodes,
-			topologyRequest: kueue.PodSetTopologyRequest{
+			topologyRequest: &kueue.PodSetTopologyRequest{
 				Required: ptr.To(tasRackLabel),
 			},
 			levels: defaultTwoLevels,
@@ -526,11 +1037,11 @@ func TestFindTopologyAssignment(t *testing.T) {
 					},
 				},
 			},
-			enableTASMostFreeCapacity: true,
+			enableFeatureGates: []featuregate.Feature{features.TASProfileMostFreeCapacity},
 		},
 		"rack required; multiple Pods fit in a rack; BestFit": {
 			nodes: defaultNodes,
-			topologyRequest: kueue.PodSetTopologyRequest{
+			topologyRequest: &kueue.PodSetTopologyRequest{
 				Required: ptr.To(tasRackLabel),
 			},
 			levels: defaultTwoLevels,
@@ -550,7 +1061,6 @@ func TestFindTopologyAssignment(t *testing.T) {
 					},
 				},
 			},
-			enableTASMostFreeCapacity: false,
 		},
 		"block preferred; Pods fit in 2 blocks; BestFit": {
 			nodes: []corev1.Node{
@@ -579,7 +1089,7 @@ func TestFindTopologyAssignment(t *testing.T) {
 					Ready().
 					Obj(),
 			},
-			topologyRequest: kueue.PodSetTopologyRequest{
+			topologyRequest: &kueue.PodSetTopologyRequest{
 				Preferred: ptr.To(tasBlockLabel),
 			},
 			levels: []string{tasBlockLabel},
@@ -604,11 +1114,10 @@ func TestFindTopologyAssignment(t *testing.T) {
 					},
 				},
 			},
-			enableTASMostFreeCapacity: false,
 		},
 		"rack required; multiple Pods fit in some racks; BestFit": {
 			nodes: defaultNodes,
-			topologyRequest: kueue.PodSetTopologyRequest{
+			topologyRequest: &kueue.PodSetTopologyRequest{
 				Required: ptr.To(tasRackLabel),
 			},
 			levels: defaultTwoLevels,
@@ -628,25 +1137,25 @@ func TestFindTopologyAssignment(t *testing.T) {
 					},
 				},
 			},
-			enableTASMostFreeCapacity: false,
 		},
 		"rack required; too many pods to fit in any rack; MostFreeCapacity": {
 			nodes: defaultNodes,
-			topologyRequest: kueue.PodSetTopologyRequest{
+			topologyRequest: &kueue.PodSetTopologyRequest{
 				Required: ptr.To(tasRackLabel),
 			},
 			levels: defaultTwoLevels,
 			requests: resources.Requests{
 				corev1.ResourceCPU: 1000,
 			},
-			count:                     4,
-			wantReason:                `topology "default" allows to fit only 3 out of 4 pod(s)`,
-			enableTASMostFreeCapacity: true,
+			count:      4,
+			wantReason: `topology "default" allows to fit only 3 out of 4 pod(s)`,
+
+			enableFeatureGates: []featuregate.Feature{features.TASProfileMostFreeCapacity},
 		},
 		"block required; single Pod fits in a block; MostFreeCapacity": {
 			// TODO: remove after dropping the TASMostFreeCapacity feature gate
 			nodes: defaultNodes,
-			topologyRequest: kueue.PodSetTopologyRequest{
+			topologyRequest: &kueue.PodSetTopologyRequest{
 				Required: ptr.To(tasBlockLabel),
 			},
 			levels: defaultTwoLevels,
@@ -669,11 +1178,63 @@ func TestFindTopologyAssignment(t *testing.T) {
 					},
 				},
 			},
-			enableTASMostFreeCapacity: true,
+			enableFeatureGates: []featuregate.Feature{features.TASProfileMostFreeCapacity},
+		},
+		"block required; single Pod fits in a block; LeastFreeCapacityFit": {
+			nodes: defaultNodes,
+			topologyRequest: &kueue.PodSetTopologyRequest{
+				Required: ptr.To(tasBlockLabel),
+			},
+			levels: defaultThreeLevels,
+			requests: resources.Requests{
+				corev1.ResourceCPU: 1000,
+			},
+			count: 1,
+			wantAssignment: &kueue.TopologyAssignment{
+				Levels: defaultOneLevel,
+				Domains: []kueue.TopologyDomainAssignment{
+					{
+						Count: 1,
+						Values: []string{
+							"x5",
+						},
+					},
+				},
+			},
+			enableFeatureGates: []featuregate.Feature{features.TASProfileLeastFreeCapacity},
+		},
+		"block required; two Pods fits in a block; LeastFreeCapacityFit": {
+			nodes: defaultNodes,
+			topologyRequest: &kueue.PodSetTopologyRequest{
+				Required: ptr.To(tasBlockLabel),
+			},
+			levels: defaultThreeLevels,
+			requests: resources.Requests{
+				corev1.ResourceCPU: 1000,
+			},
+			count: 2,
+			wantAssignment: &kueue.TopologyAssignment{
+				Levels: defaultOneLevel,
+				Domains: []kueue.TopologyDomainAssignment{
+					{
+						Count: 1,
+						Values: []string{
+							"x5",
+						},
+					},
+					{
+						Count: 1,
+						Values: []string{
+							"x6",
+						},
+					},
+				},
+			},
+			enableFeatureGates: []featuregate.Feature{features.TASProfileLeastFreeCapacity},
 		},
 		"block required; single Pod fits in a block and a single rack; BestFit": {
 			nodes: defaultNodes,
-			topologyRequest: kueue.PodSetTopologyRequest{
+			topologyRequest: &kueue.PodSetTopologyRequest{
 				Required: ptr.To(tasBlockLabel),
 			},
 			levels: defaultTwoLevels,
@@ -696,11 +1257,10 @@ func TestFindTopologyAssignment(t *testing.T) {
 					},
 				},
 			},
-			enableTASMostFreeCapacity: false,
 		},
 		"block required; single Pod fits in a block spread across two racks; BestFit": {
 			nodes: defaultNodes,
-			topologyRequest: kueue.PodSetTopologyRequest{
+			topologyRequest: &kueue.PodSetTopologyRequest{
 				Required: ptr.To(tasBlockLabel),
 			},
 			levels: defaultTwoLevels,
@@ -730,11 +1290,10 @@ func TestFindTopologyAssignment(t *testing.T) {
 					},
 				},
 			},
-			enableTASMostFreeCapacity: false,
 		},
 		"block required; Pods fit in a block spread across two racks; MostFreeCapacity": {
 			nodes: defaultNodes,
-			topologyRequest: kueue.PodSetTopologyRequest{
+			topologyRequest: &kueue.PodSetTopologyRequest{
 				Required: ptr.To(tasBlockLabel),
 			},
 			levels: defaultTwoLevels,
@@ -761,38 +1320,38 @@ func TestFindTopologyAssignment(t *testing.T) {
 					},
 				},
 			},
-			enableTASMostFreeCapacity: true,
+			enableFeatureGates: []featuregate.Feature{features.TASProfileMostFreeCapacity},
 		},
 		"block required; single Pod which cannot be split; MostFreeCapacity": {
 			nodes: defaultNodes,
-			topologyRequest: kueue.PodSetTopologyRequest{
+			topologyRequest: &kueue.PodSetTopologyRequest{
 				Required: ptr.To(tasBlockLabel),
 			},
 			levels: defaultTwoLevels,
 			requests: resources.Requests{
 				corev1.ResourceCPU: 4000,
 			},
-			count:                     1,
-			wantReason:                `topology "default" doesn't allow to fit any of 1 pod(s)`,
-			enableTASMostFreeCapacity: true,
+			count:              1,
+			wantReason:         `topology "default" doesn't allow to fit any of 1 pod(s)`,
+			enableFeatureGates: []featuregate.Feature{features.TASProfileMostFreeCapacity},
 		},
 		"block required; too many Pods to fit requested; MostFreeCapacity": {
 			nodes: defaultNodes,
-			topologyRequest: kueue.PodSetTopologyRequest{
+			topologyRequest: &kueue.PodSetTopologyRequest{
 				Required: ptr.To(tasBlockLabel),
 			},
 			levels: defaultTwoLevels,
 			requests: resources.Requests{
 				corev1.ResourceCPU: 1000,
 			},
-			count:                     5,
-			wantReason:                `topology "default" allows to fit only 4 out of 5 pod(s)`,
-			enableTASMostFreeCapacity: true,
+			count:              5,
+			wantReason:         `topology "default" allows to fit only 4 out of 5 pod(s)`,
+			enableFeatureGates: []featuregate.Feature{features.TASProfileMostFreeCapacity},
 		},
 		"rack required; single Pod requiring memory; MostFreeCapacity": {
 			// TODO: remove after dropping the TASMostFreeCapacity feature gate
 			nodes: defaultNodes,
-			topologyRequest: kueue.PodSetTopologyRequest{
+			topologyRequest: &kueue.PodSetTopologyRequest{
 				Required: ptr.To(tasRackLabel),
 			},
 			levels: defaultTwoLevels,
@@ -812,11 +1371,11 @@ func TestFindTopologyAssignment(t *testing.T) {
 					},
 				},
 			},
-			enableTASMostFreeCapacity: true,
+			enableFeatureGates: []featuregate.Feature{features.TASProfileMostFreeCapacity},
 		},
 		"rack preferred; but only block can accommodate the workload; MostFreeCapacity": {
 			nodes: defaultNodes,
-			topologyRequest: kueue.PodSetTopologyRequest{
+			topologyRequest: &kueue.PodSetTopologyRequest{
 				Preferred: ptr.To(tasRackLabel),
 			},
 			levels: defaultTwoLevels,
@@ -843,11 +1402,11 @@ func TestFindTopologyAssignment(t *testing.T) {
 					},
 				},
 			},
-			enableTASMostFreeCapacity: true,
+			enableFeatureGates: []featuregate.Feature{features.TASProfileMostFreeCapacity},
 		},
 		"rack preferred; but only multiple blocks can accommodate the workload; MostFreeCapacity": {
 			nodes: defaultNodes,
-			topologyRequest: kueue.PodSetTopologyRequest{
+			topologyRequest: &kueue.PodSetTopologyRequest{
 				Preferred: ptr.To(tasRackLabel),
 			},
 			levels: defaultTwoLevels,
@@ -881,11 +1440,11 @@ func TestFindTopologyAssignment(t *testing.T) {
 					},
 				},
 			},
-			enableTASMostFreeCapacity: true,
+			enableFeatureGates: []featuregate.Feature{features.TASProfileMostFreeCapacity},
 		},
 		"block preferred; but only multiple blocks can accommodate the workload; MostFreeCapacity": {
 			nodes: defaultNodes,
-			topologyRequest: kueue.PodSetTopologyRequest{
+			topologyRequest: &kueue.PodSetTopologyRequest{
 				Preferred: ptr.To(tasBlockLabel),
 			},
 			levels: defaultTwoLevels,
@@ -919,20 +1478,20 @@ func TestFindTopologyAssignment(t *testing.T) {
 					},
 				},
 			},
-			enableTASMostFreeCapacity: true,
+			enableFeatureGates: []featuregate.Feature{features.TASProfileMostFreeCapacity},
 		},
 		"block preferred; but the workload cannot be accommodate in entire topology; MostFreeCapacity": {
 			nodes: defaultNodes,
-			topologyRequest: kueue.PodSetTopologyRequest{
+			topologyRequest: &kueue.PodSetTopologyRequest{
 				Preferred: ptr.To(tasBlockLabel),
 			},
 			levels: defaultTwoLevels,
 			requests: resources.Requests{
 				corev1.ResourceCPU: 1000,
 			},
-			count:                     10,
-			wantReason:                `topology "default" allows to fit only 7 out of 10 pod(s)`,
-			enableTASMostFreeCapacity: true,
+			count:              10,
+			wantReason:         `topology "default" allows to fit only 7 out of 10 pod(s)`,
+			enableFeatureGates: []featuregate.Feature{features.TASProfileMostFreeCapacity},
 		},
 		"only nodes with matching labels are considered; no matching node; MostFreeCapacity": {
 			nodes: []corev1.Node{
@@ -946,7 +1505,7 @@ func TestFindTopologyAssignment(t *testing.T) {
 					}).
 					Obj(),
 			},
-			topologyRequest: kueue.PodSetTopologyRequest{
+			topologyRequest: &kueue.PodSetTopologyRequest{
 				Required: ptr.To(corev1.LabelHostname),
 			},
 			nodeLabels: map[string]string{
@@ -956,9 +1515,9 @@ func TestFindTopologyAssignment(t *testing.T) {
 			requests: resources.Requests{
 				corev1.ResourceCPU: 1000,
 			},
-			count:                     1,
-			wantReason:                "no topology domains at level: kubernetes.io/hostname",
-			enableTASMostFreeCapacity: true,
+			count:              1,
+			wantReason:         "no topology domains at level: kubernetes.io/hostname",
+			enableFeatureGates: []featuregate.Feature{features.TASProfileMostFreeCapacity},
 		},
 		"only nodes with matching labels are considered; matching node is found; MostFreeCapacity": {
 			nodes: []corev1.Node{
@@ -973,7 +1532,7 @@ func TestFindTopologyAssignment(t *testing.T) {
 					Ready().
 					Obj(),
 			},
-			topologyRequest: kueue.PodSetTopologyRequest{
+			topologyRequest: &kueue.PodSetTopologyRequest{
 				Required: ptr.To(corev1.LabelHostname),
 			},
 			nodeLabels: map[string]string{
@@ -995,7 +1554,7 @@ func TestFindTopologyAssignment(t *testing.T) {
 					},
 				},
 			},
-			enableTASMostFreeCapacity: true,
+			enableFeatureGates: []featuregate.Feature{features.TASProfileMostFreeCapacity},
 		},
 		"only nodes with matching levels are considered; no host label on node; MostFreeCapacity": {
 			nodes: []corev1.Node{
@@ -1011,16 +1570,16 @@ func TestFindTopologyAssignment(t *testing.T) {
 					Ready().
 					Obj(),
 			},
-			topologyRequest: kueue.PodSetTopologyRequest{
+			topologyRequest: &kueue.PodSetTopologyRequest{
 				Required: ptr.To(tasRackLabel),
 			},
 			levels: defaultThreeLevels,
 			requests: resources.Requests{
 				corev1.ResourceCPU: 1000,
 			},
-			count:                     1,
-			wantReason:                "no topology domains at level: cloud.com/topology-rack",
-			enableTASMostFreeCapacity: true,
+			count:              1,
+			wantReason:         "no topology domains at level: cloud.com/topology-rack",
+			enableFeatureGates: []featuregate.Feature{features.TASProfileMostFreeCapacity},
 		},
 		"don't consider unscheduled Pods when computing capacity; MostFreeCapacity": {
 			// the Pod is not scheduled (no NodeName set, so is not blocking capacity)
@@ -1040,7 +1599,7 @@ func TestFindTopologyAssignment(t *testing.T) {
 					Request(corev1.ResourceCPU, "600m").
 					Obj(),
 			},
-			topologyRequest: kueue.PodSetTopologyRequest{
+			topologyRequest: &kueue.PodSetTopologyRequest{
 				Required: ptr.To(corev1.LabelHostname),
 			},
 			levels: defaultOneLevel,
@@ -1059,7 +1618,7 @@ func TestFindTopologyAssignment(t *testing.T) {
 					},
 				},
 			},
-			enableTASMostFreeCapacity: true,
+			enableFeatureGates: []featuregate.Feature{features.TASProfileMostFreeCapacity},
 		},
 		"don't consider terminal pods when computing the capacity; MostFreeCapacity": {
 			nodes: []corev1.Node{
@@ -1083,7 +1642,7 @@ func TestFindTopologyAssignment(t *testing.T) {
 					StatusPhase(corev1.PodSucceeded).
 					Obj(),
 			},
-			topologyRequest: kueue.PodSetTopologyRequest{
+			topologyRequest: &kueue.PodSetTopologyRequest{
 				Required: ptr.To(corev1.LabelHostname),
 			},
 			levels: defaultOneLevel,
@@ -1102,7 +1661,7 @@ func TestFindTopologyAssignment(t *testing.T) {
 					},
 				},
 			},
-			enableTASMostFreeCapacity: true,
+			enableFeatureGates: []featuregate.Feature{features.TASProfileMostFreeCapacity},
 		},
 		"include usage from pending scheduled non-TAS pods, blocked assignment; MostFreeCapacity": {
 			// there is not enough free capacity on the only node x1
@@ -1123,16 +1682,15 @@ func TestFindTopologyAssignment(t *testing.T) {
 					Request(corev1.ResourceCPU, "600m").
 					Obj(),
 			},
-			topologyRequest: kueue.PodSetTopologyRequest{
+			topologyRequest: &kueue.PodSetTopologyRequest{
 				Required: ptr.To(corev1.LabelHostname),
 			},
 			levels: defaultOneLevel,
 			requests: resources.Requests{
 				corev1.ResourceCPU: 600,
 			},
-			count:                     1,
-			wantReason:                `topology "default" doesn't allow to fit any of 1 pod(s)`,
-			enableTASMostFreeCapacity: true,
+			count:      1,
+			wantReason: `topology "default" doesn't allow to fit any of 1 pod(s)`,
 		},
 		"include usage from running non-TAS pods, blocked assignment; MostFreeCapacity": {
 			// there is not enough free capacity on the only node x1
@@ -1153,16 +1711,16 @@ func TestFindTopologyAssignment(t *testing.T) {
 					Request(corev1.ResourceCPU, "600m").
 					Obj(),
 			},
-			topologyRequest: kueue.PodSetTopologyRequest{
+			topologyRequest: &kueue.PodSetTopologyRequest{
 				Required: ptr.To(corev1.LabelHostname),
 			},
 			levels: defaultOneLevel,
 			requests: resources.Requests{
 				corev1.ResourceCPU: 600,
 			},
-			count:                     1,
-			wantReason:                `topology "default" doesn't allow to fit any of 1 pod(s)`,
-			enableTASMostFreeCapacity: true,
+			count:              1,
+			wantReason:         `topology "default" doesn't allow to fit any of 1 pod(s)`,
+			enableFeatureGates: []featuregate.Feature{features.TASProfileMostFreeCapacity},
 		},
 		"include usage from running non-TAS pods, found free capacity on another node; MostFreeCapacity": {
 			// there is not enough free capacity on the node x1 as the
@@ -1192,7 +1750,7 @@ func TestFindTopologyAssignment(t *testing.T) {
 					Request(corev1.ResourceCPU, "600m").
 					Obj(),
 			},
-			topologyRequest: kueue.PodSetTopologyRequest{
+			topologyRequest: &kueue.PodSetTopologyRequest{
 				Required: ptr.To(corev1.LabelHostname),
 			},
 			levels: defaultOneLevel,
@@ -1211,7 +1769,7 @@ func TestFindTopologyAssignment(t *testing.T) {
 					},
 				},
 			},
-			enableTASMostFreeCapacity: true,
+			enableFeatureGates: []featuregate.Feature{features.TASProfileMostFreeCapacity},
 		},
 		"no assignment as node is not ready; MostFreeCapacity": {
 			nodes: []corev1.Node{
@@ -1230,7 +1788,7 @@ func TestFindTopologyAssignment(t *testing.T) {
 					}).
 					Obj(),
 			},
-			topologyRequest: kueue.PodSetTopologyRequest{
+			topologyRequest: &kueue.PodSetTopologyRequest{
 				Required: ptr.To(corev1.LabelHostname),
 			},
 			nodeLabels: map[string]string{
@@ -1240,9 +1798,9 @@ func TestFindTopologyAssignment(t *testing.T) {
 			requests: resources.Requests{
 				corev1.ResourceCPU: 1000,
 			},
-			count:                     1,
-			wantReason:                "no topology domains at level: kubernetes.io/hostname",
-			enableTASMostFreeCapacity: true,
+			count:              1,
+			wantReason:         "no topology domains at level: kubernetes.io/hostname",
+			enableFeatureGates: []featuregate.Feature{features.TASProfileMostFreeCapacity},
 		},
 		"no assignment as node is unschedulable; MostFreeCapacity": {
 			nodes: []corev1.Node{
@@ -1258,7 +1816,7 @@ func TestFindTopologyAssignment(t *testing.T) {
 					Unschedulable().
 					Obj(),
 			},
-			topologyRequest: kueue.PodSetTopologyRequest{
+			topologyRequest: &kueue.PodSetTopologyRequest{
 				Required: ptr.To(corev1.LabelHostname),
 			},
 			nodeLabels: map[string]string{
@@ -1268,9 +1826,9 @@ func TestFindTopologyAssignment(t *testing.T) {
 			requests: resources.Requests{
 				corev1.ResourceCPU: 1000,
 			},
-			count:                     1,
-			wantReason:                "no topology domains at level: kubernetes.io/hostname",
-			enableTASMostFreeCapacity: true,
+			count:              1,
+			wantReason:         "no topology domains at level: kubernetes.io/hostname",
+			enableFeatureGates: []featuregate.Feature{features.TASProfileMostFreeCapacity},
 		},
 		"skip node which has untolerated taint; MostFreeCapacity": {
 			nodes: []corev1.Node{
@@ -1290,7 +1848,7 @@ func TestFindTopologyAssignment(t *testing.T) {
 					}).
 					Obj(),
 			},
-			topologyRequest: kueue.PodSetTopologyRequest{
+			topologyRequest: &kueue.PodSetTopologyRequest{
 				Required: ptr.To(corev1.LabelHostname),
 			},
 			nodeLabels: map[string]string{
@@ -1300,9 +1858,9 @@ func TestFindTopologyAssignment(t *testing.T) {
 			requests: resources.Requests{
 				corev1.ResourceCPU: 1000,
 			},
-			count:                     1,
-			wantReason:                `topology "default" doesn't allow to fit any of 1 pod(s)`,
-			enableTASMostFreeCapacity: true,
+			count:              1,
+			wantReason:         `topology "default" doesn't allow to fit any of 1 pod(s)`,
+			enableFeatureGates: []featuregate.Feature{features.TASProfileMostFreeCapacity},
 		},
 		"allow to schedule on node with tolerated taint; MostFreeCapacity": {
 			nodes: []corev1.Node{
@@ -1329,7 +1887,7 @@ func TestFindTopologyAssignment(t *testing.T) {
 					Operator: corev1.TolerationOpEqual,
 				},
 			},
-			topologyRequest: kueue.PodSetTopologyRequest{
+			topologyRequest: &kueue.PodSetTopologyRequest{
 				Required: ptr.To(corev1.LabelHostname),
 			},
 			nodeLabels: map[string]string{
@@ -1351,7 +1909,7 @@ func TestFindTopologyAssignment(t *testing.T) {
 					},
 				},
 			},
-			enableTASMostFreeCapacity: true,
+			enableFeatureGates: []featuregate.Feature{features.TASProfileMostFreeCapacity},
 		},
 		"no assignment as node does not have enough allocatable pods (.status.allocatable['pods']); MostFreeCapacity": {
 			nodes: []corev1.Node{
@@ -1372,7 +1930,7 @@ func TestFindTopologyAssignment(t *testing.T) {
 					Request(corev1.ResourceCPU, "300m").
 					Obj(),
 			},
-			topologyRequest: kueue.PodSetTopologyRequest{
+			topologyRequest: &kueue.PodSetTopologyRequest{
 				Required: ptr.To(corev1.LabelHostname),
 			},
 			nodeLabels: map[string]string{
@@ -1382,16 +1940,18 @@ func TestFindTopologyAssignment(t *testing.T) {
 			requests: resources.Requests{
 				corev1.ResourceCPU: 300,
 			},
-			count:                     1,
-			wantReason:                `topology "default" doesn't allow to fit any of 1 pod(s)`,
-			enableTASMostFreeCapacity: true,
+			count:              1,
+			wantReason:         `topology "default" doesn't allow to fit any of 1 pod(s)`,
+			enableFeatureGates: []featuregate.Feature{features.TASProfileMostFreeCapacity},
 		},
 	}
 	for name, tc := range cases {
 		t.Run(name, func(t *testing.T) {
 			ctx, _ := utiltesting.ContextWithLog(t)
-			// TODO: remove after dropping the TASMostFreeCapacity feature gate
-			features.SetFeatureGateDuringTest(t, features.TASMostFreeCapacity, tc.enableTASMostFreeCapacity)
+			// TODO: remove after dropping the TAS profiles feature gates
+			for _, gate := range tc.enableFeatureGates {
+				features.SetFeatureGateDuringTest(t, gate, true)
+			}
 
 			initialObjects := make([]client.Object, 0)
 			for i := range tc.nodes {
@@ -1415,7 +1975,7 @@ func TestFindTopologyAssignment(t *testing.T) {
 			tasInput := TASPodSetRequests{
 				PodSet: &kueue.PodSet{
 					Name:            kueue.DefaultPodSetName,
-					TopologyRequest: &tc.topologyRequest,
+					TopologyRequest: tc.topologyRequest,
 					Template: corev1.PodTemplateSpec{
 						Spec: corev1.PodSpec{
 							Tolerations: tc.tolerations,
@@ -1425,6 +1985,9 @@ func TestFindTopologyAssignment(t *testing.T) {
 				SinglePodRequests: tc.requests,
 				Count:             tc.count,
 			}
+			if tc.topologyRequest == nil {
+				tasInput.Implied = true
+			}
 			flavorTASRequests := []TASPodSetRequests{tasInput}
 			wantResult := make(TASAssignmentsResult)
 			wantMainPodSetResult := tasPodSetAssignmentResult{
diff --git a/pkg/config/validation_test.go b/pkg/config/validation_test.go
index e278bade6..ac09c65b8 100644
--- a/pkg/config/validation_test.go
+++ b/pkg/config/validation_test.go
@@ -772,6 +772,20 @@ func TestValidateFeatureGates(t *testing.T) {
 
 			errorStr: "feature gates for CLI and configuration cannot both specified",
 		},
+		"cannot specify more than one TAS profile using GateMap": {
+			featureGateMap: map[string]bool{"TASProfileMostFreeCapacity": true,
+				"TASProfileLeastFreeCapacity": true},
+			errorStr: "Cannot use more than one TAS profiles",
+		},
+		"cannot specify more than one TAS profile using GatesCLI": {
+			featureGatesCLI: "TASProfileMostFreeCapacity:true,TASProfileMixed:true",
+			errorStr:        "Cannot use more than one TAS profiles",
+		},
+		"cannot set TAS profile with TAS disabled": {
+			featureGateMap: map[string]bool{"TASProfileMostFreeCapacity": true,
+				"TopologyAwareScheduling": true},
+			errorStr: "Cannot use a TAS profile with TAS disabled",
+		},
 	}
 	for name, tc := range cases {
 		t.Run(name, func(t *testing.T) {
diff --git a/pkg/controller/jobs/job/job_webhook_test.go b/pkg/controller/jobs/job/job_webhook_test.go
index d7c8f8cc8..f9fd1b802 100644
--- a/pkg/controller/jobs/job/job_webhook_test.go
+++ b/pkg/controller/jobs/job/job_webhook_test.go
@@ -252,7 +252,8 @@ func TestValidateCreate(t *testing.T) {
 				Obj(),
 			wantErr: field.ErrorList{
 				field.Invalid(replicaMetaPath.Child("annotations"), field.OmitValueType{},
-					`must not contain both "kueue.x-k8s.io/podset-required-topology" and "kueue.x-k8s.io/podset-preferred-topology"`),
+					`must not contain more than one topology annotation: ["kueue.x-k8s.io/podset-required-topology", `+
+						`"kueue.x-k8s.io/podset-preferred-topology", "kueue.x-k8s.io/podset-unconstrained-topology"]`),
 			},
 		},
 		{
@@ -531,8 +532,8 @@ func TestValidateUpdate(t *testing.T) {
 				Obj(),
 			wantErr: field.ErrorList{
 				field.Invalid(replicaMetaPath.Child("annotations"), field.OmitValueType{},
-					`must not contain both "kueue.x-k8s.io/podset-required-topology" and "kueue.x-k8s.io/podset-preferred-topology"`),
-			},
+					`must not contain more than one topology annotation: ["kueue.x-k8s.io/podset-required-topology", `+
+						`"kueue.x-k8s.io/podset-preferred-topology", "kueue.x-k8s.io/podset-unconstrained-topology"]`)},
 		},
 	}
 
diff --git a/pkg/controller/jobs/jobset/jobset_webhook_test.go b/pkg/controller/jobs/jobset/jobset_webhook_test.go
index 3f4df6080..91e3f15bb 100644
--- a/pkg/controller/jobs/jobset/jobset_webhook_test.go
+++ b/pkg/controller/jobs/jobset/jobset_webhook_test.go
@@ -98,7 +98,8 @@ func TestValidateCreate(t *testing.T) {
 				},
 			}).Obj(),
 			wantErr: field.ErrorList{field.Invalid(field.NewPath("spec.replicatedJobs[1].template.metadata.annotations"),
-				field.OmitValueType{}, `must not contain both "kueue.x-k8s.io/podset-required-topology" and "kueue.x-k8s.io/podset-preferred-topology"`)}.ToAggregate(),
+				field.OmitValueType{}, `must not contain more than one topology annotation: ["kueue.x-k8s.io/podset-required-topology", `+
+					`"kueue.x-k8s.io/podset-preferred-topology", "kueue.x-k8s.io/podset-unconstrained-topology"]`)}.ToAggregate(),
 		},
 	}
 
@@ -148,7 +149,8 @@ func TestValidateUpdate(t *testing.T) {
 				},
 			}).Obj(),
 			wantErr: field.ErrorList{field.Invalid(field.NewPath("spec.replicatedJobs[0].template.metadata.annotations"),
-				field.OmitValueType{}, `must not contain both "kueue.x-k8s.io/podset-required-topology" and "kueue.x-k8s.io/podset-preferred-topology"`)},
+				field.OmitValueType{}, `must not contain more than one topology annotation: ["kueue.x-k8s.io/podset-required-topology", `+
+					`"kueue.x-k8s.io/podset-preferred-topology", "kueue.x-k8s.io/podset-unconstrained-topology"]`)},
 		},
 	}
 
diff --git a/pkg/controller/jobs/kubeflow/jobs/paddlejob/paddlejob_controller_test.go b/pkg/controller/jobs/kubeflow/jobs/paddlejob/paddlejob_controller_test.go
index 86941e199..8deb25c65 100644
--- a/pkg/controller/jobs/kubeflow/jobs/paddlejob/paddlejob_controller_test.go
+++ b/pkg/controller/jobs/kubeflow/jobs/paddlejob/paddlejob_controller_test.go
@@ -365,15 +365,15 @@ func TestValidate(t *testing.T) {
 						Key("Master").
 						Child("template", "metadata", "annotations"),
 					field.OmitValueType{},
-					`must not contain both "kueue.x-k8s.io/podset-required-topology" and "kueue.x-k8s.io/podset-preferred-topology"`,
-				),
+					`must not contain more than one topology annotation: ["kueue.x-k8s.io/podset-required-topology", `+
+						`"kueue.x-k8s.io/podset-preferred-topology", "kueue.x-k8s.io/podset-unconstrained-topology"]`),
 				field.Invalid(
 					field.NewPath("spec", "paddleReplicaSpecs").
 						Key("Worker").
 						Child("template", "metadata", "annotations"),
 					field.OmitValueType{},
-					`must not contain both "kueue.x-k8s.io/podset-required-topology" and "kueue.x-k8s.io/podset-preferred-topology"`,
-				),
+					`must not contain more than one topology annotation: ["kueue.x-k8s.io/podset-required-topology", `+
+						`"kueue.x-k8s.io/podset-preferred-topology", "kueue.x-k8s.io/podset-unconstrained-topology"]`),
 			},
 		},
 	}
diff --git a/pkg/controller/jobs/kubeflow/jobs/pytorchjob/pytorchjob_controller_test.go b/pkg/controller/jobs/kubeflow/jobs/pytorchjob/pytorchjob_controller_test.go
index 2a43e579e..6d5a661c8 100644
--- a/pkg/controller/jobs/kubeflow/jobs/pytorchjob/pytorchjob_controller_test.go
+++ b/pkg/controller/jobs/kubeflow/jobs/pytorchjob/pytorchjob_controller_test.go
@@ -368,15 +368,15 @@ func TestValidate(t *testing.T) {
 						Key("Master").
 						Child("template", "metadata", "annotations"),
 					field.OmitValueType{},
-					`must not contain both "kueue.x-k8s.io/podset-required-topology" and "kueue.x-k8s.io/podset-preferred-topology"`,
-				),
+					`must not contain more than one topology annotation: ["kueue.x-k8s.io/podset-required-topology", `+
+						`"kueue.x-k8s.io/podset-preferred-topology", "kueue.x-k8s.io/podset-unconstrained-topology"]`),
 				field.Invalid(
 					field.NewPath("spec", "pytorchReplicaSpecs").
 						Key("Worker").
 						Child("template", "metadata", "annotations"),
 					field.OmitValueType{},
-					`must not contain both "kueue.x-k8s.io/podset-required-topology" and "kueue.x-k8s.io/podset-preferred-topology"`,
-				),
+					`must not contain more than one topology annotation: ["kueue.x-k8s.io/podset-required-topology", `+
+						`"kueue.x-k8s.io/podset-preferred-topology", "kueue.x-k8s.io/podset-unconstrained-topology"]`),
 			},
 		},
 	}
diff --git a/pkg/controller/jobs/kubeflow/jobs/tfjob/tfjob_controller_test.go b/pkg/controller/jobs/kubeflow/jobs/tfjob/tfjob_controller_test.go
index c496ceb4a..dab1a8d3e 100644
--- a/pkg/controller/jobs/kubeflow/jobs/tfjob/tfjob_controller_test.go
+++ b/pkg/controller/jobs/kubeflow/jobs/tfjob/tfjob_controller_test.go
@@ -385,15 +385,15 @@ func TestValidate(t *testing.T) {
 						Key("Chief").
 						Child("template", "metadata", "annotations"),
 					field.OmitValueType{},
-					`must not contain both "kueue.x-k8s.io/podset-required-topology" and "kueue.x-k8s.io/podset-preferred-topology"`,
-				),
+					`must not contain more than one topology annotation: ["kueue.x-k8s.io/podset-required-topology", `+
+						`"kueue.x-k8s.io/podset-preferred-topology", "kueue.x-k8s.io/podset-unconstrained-topology"]`),
 				field.Invalid(
 					field.NewPath("spec", "tfReplicaSpecs").
 						Key("PS").
 						Child("template", "metadata", "annotations"),
 					field.OmitValueType{},
-					`must not contain both "kueue.x-k8s.io/podset-required-topology" and "kueue.x-k8s.io/podset-preferred-topology"`,
-				),
+					`must not contain more than one topology annotation: ["kueue.x-k8s.io/podset-required-topology", `+
+						`"kueue.x-k8s.io/podset-preferred-topology", "kueue.x-k8s.io/podset-unconstrained-topology"]`),
 			},
 		},
 	}
diff --git a/pkg/controller/jobs/kubeflow/jobs/xgboostjob/xgboostjob_controller_test.go b/pkg/controller/jobs/kubeflow/jobs/xgboostjob/xgboostjob_controller_test.go
index a9c130762..e5b817afa 100644
--- a/pkg/controller/jobs/kubeflow/jobs/xgboostjob/xgboostjob_controller_test.go
+++ b/pkg/controller/jobs/kubeflow/jobs/xgboostjob/xgboostjob_controller_test.go
@@ -374,15 +374,15 @@ func TestValidate(t *testing.T) {
 						Key("Master").
 						Child("template", "metadata", "annotations"),
 					field.OmitValueType{},
-					`must not contain both "kueue.x-k8s.io/podset-required-topology" and "kueue.x-k8s.io/podset-preferred-topology"`,
-				),
+					`must not contain more than one topology annotation: ["kueue.x-k8s.io/podset-required-topology", `+
+						`"kueue.x-k8s.io/podset-preferred-topology", "kueue.x-k8s.io/podset-unconstrained-topology"]`),
 				field.Invalid(
 					field.NewPath("spec", "xgbReplicaSpecs").
 						Key("Worker").
 						Child("template", "metadata", "annotations"),
 					field.OmitValueType{},
-					`must not contain both "kueue.x-k8s.io/podset-required-topology" and "kueue.x-k8s.io/podset-preferred-topology"`,
-				),
+					`must not contain more than one topology annotation: ["kueue.x-k8s.io/podset-required-topology", `+
+						`"kueue.x-k8s.io/podset-preferred-topology", "kueue.x-k8s.io/podset-unconstrained-topology"]`),
 			},
 		},
 	}
diff --git a/pkg/controller/jobs/mpijob/mpijob_webhook_test.go b/pkg/controller/jobs/mpijob/mpijob_webhook_test.go
index 61c0f8356..0e0fb0620 100644
--- a/pkg/controller/jobs/mpijob/mpijob_webhook_test.go
+++ b/pkg/controller/jobs/mpijob/mpijob_webhook_test.go
@@ -110,13 +110,13 @@ func TestValidateCreate(t *testing.T) {
 				field.Invalid(
 					field.NewPath("spec.mpiReplicaSpecs[Launcher].template.metadata.annotations"),
 					field.OmitValueType{},
-					`must not contain both "kueue.x-k8s.io/podset-required-topology" and "kueue.x-k8s.io/podset-preferred-topology"`,
-				),
+					`must not contain more than one topology annotation: ["kueue.x-k8s.io/podset-required-topology", `+
+						`"kueue.x-k8s.io/podset-preferred-topology", "kueue.x-k8s.io/podset-unconstrained-topology"]`),
 				field.Invalid(
 					field.NewPath("spec.mpiReplicaSpecs[Worker].template.metadata.annotations"),
 					field.OmitValueType{},
-					`must not contain both "kueue.x-k8s.io/podset-required-topology" and "kueue.x-k8s.io/podset-preferred-topology"`,
-				),
+					`must not contain more than one topology annotation: ["kueue.x-k8s.io/podset-required-topology", `+
+						`"kueue.x-k8s.io/podset-preferred-topology", "kueue.x-k8s.io/podset-unconstrained-topology"]`),
 			}.ToAggregate(),
 		},
 	}
diff --git a/pkg/controller/jobs/raycluster/raycluster_webhook_test.go b/pkg/controller/jobs/raycluster/raycluster_webhook_test.go
index 02884ab9f..2c55411ef 100644
--- a/pkg/controller/jobs/raycluster/raycluster_webhook_test.go
+++ b/pkg/controller/jobs/raycluster/raycluster_webhook_test.go
@@ -240,13 +240,13 @@ func TestValidateCreate(t *testing.T) {
 				field.Invalid(
 					field.NewPath("spec.headGroupSpec.template, metadata.annotations"),
 					field.OmitValueType{},
-					`must not contain both "kueue.x-k8s.io/podset-required-topology" and "kueue.x-k8s.io/podset-preferred-topology"`,
-				),
+					`must not contain more than one topology annotation: ["kueue.x-k8s.io/podset-required-topology", `+
+						`"kueue.x-k8s.io/podset-preferred-topology", "kueue.x-k8s.io/podset-unconstrained-topology"]`),
 				field.Invalid(
 					field.NewPath("spec.workerGroupSpecs[0].template.metadata.annotations"),
 					field.OmitValueType{},
-					`must not contain both "kueue.x-k8s.io/podset-required-topology" and "kueue.x-k8s.io/podset-preferred-topology"`,
-				),
+					`must not contain more than one topology annotation: ["kueue.x-k8s.io/podset-required-topology", `+
+						`"kueue.x-k8s.io/podset-preferred-topology", "kueue.x-k8s.io/podset-unconstrained-topology"]`),
 			}.ToAggregate(),
 		},
 	}
diff --git a/pkg/controller/jobs/rayjob/rayjob_webhook_test.go b/pkg/controller/jobs/rayjob/rayjob_webhook_test.go
index 92873ac90..e34c6ac55 100644
--- a/pkg/controller/jobs/rayjob/rayjob_webhook_test.go
+++ b/pkg/controller/jobs/rayjob/rayjob_webhook_test.go
@@ -267,13 +267,13 @@ func TestValidateCreate(t *testing.T) {
 				field.Invalid(
 					field.NewPath("spec.rayClusterSpec.headGroupSpec.template, metadata.annotations"),
 					field.OmitValueType{},
-					`must not contain both "kueue.x-k8s.io/podset-required-topology" and "kueue.x-k8s.io/podset-preferred-topology"`,
-				),
+					`must not contain more than one topology annotation: ["kueue.x-k8s.io/podset-required-topology", `+
+						`"kueue.x-k8s.io/podset-preferred-topology", "kueue.x-k8s.io/podset-unconstrained-topology"]`),
 				field.Invalid(
 					field.NewPath("spec.rayClusterSpec.workerGroupSpecs[0].template.metadata.annotations"),
 					field.OmitValueType{},
-					`must not contain both "kueue.x-k8s.io/podset-required-topology" and "kueue.x-k8s.io/podset-preferred-topology"`,
-				),
+					`must not contain more than one topology annotation: ["kueue.x-k8s.io/podset-required-topology", `+
+						`"kueue.x-k8s.io/podset-preferred-topology", "kueue.x-k8s.io/podset-unconstrained-topology"]`),
 			}.ToAggregate(),
 		},
 	}
diff --git a/pkg/scheduler/preemption/preemption_test.go b/pkg/scheduler/preemption/preemption_test.go
index 364f323d5..f79ef5a81 100644
--- a/pkg/scheduler/preemption/preemption_test.go
+++ b/pkg/scheduler/preemption/preemption_test.go
@@ -2342,6 +2342,25 @@ func TestFairPreemptions(t *testing.T) {
 			incoming: unitWl.Clone().Name("a_incoming").Obj(),
 			targetCQ: "a",
 		},
+		"can preempt within cluster queue when no cohort": {
+			clusterQueues: []*kueue.ClusterQueue{
+				utiltesting.MakeClusterQueue("a").
+					ResourceGroup(*utiltesting.MakeFlavorQuotas("default").
+						Resource(corev1.ResourceCPU, "1").Obj()).
+					Preemption(kueue.ClusterQueuePreemption{
+						WithinClusterQueue: kueue.PreemptionPolicyLowerPriority,
+					}).
+					Obj(),
+			},
+			admitted: []kueue.Workload{
+				*unitWl.Clone().Name("a1").SimpleReserveQuota("a", "default", now).Obj(),
+			},
+			incoming: unitWl.Clone().Name("a_incoming").Priority(1000).Obj(),
+			targetCQ: "a",
+			wantPreempted: sets.New(
+				targetKeyReason("/a1", kueue.InClusterQueueReason),
+			),
+		},
 	}
 	for name, tc := range cases {
 		t.Run(name, func(t *testing.T) {
diff --git a/pkg/util/testing/wrappers.go b/pkg/util/testing/wrappers.go
index 5cc5f68b2..f1f408708 100644
--- a/pkg/util/testing/wrappers.go
+++ b/pkg/util/testing/wrappers.go
@@ -122,6 +122,10 @@ func (w *WorkloadWrapper) Limit(r corev1.ResourceName, q string) *WorkloadWrappe
 	return w
 }
 
+func (w *WorkloadWrapper) RequestAndLimit(r corev1.ResourceName, q string) *WorkloadWrapper {
+	return w.Request(r, q).Limit(r, q)
+}
+
 func (w *WorkloadWrapper) Queue(q string) *WorkloadWrapper {
 	w.Spec.QueueName = q
 	return w
diff --git a/pkg/util/testingjobs/appwrapper/wrappers.go b/pkg/util/testingjobs/appwrapper/wrappers.go
index e49b44022..3294aa237 100644
--- a/pkg/util/testingjobs/appwrapper/wrappers.go
+++ b/pkg/util/testingjobs/appwrapper/wrappers.go
@@ -152,7 +152,7 @@ func (aw *AppWrapperWrapper) Suspend(s bool) *AppWrapperWrapper {
 	return aw
 }
 
-// StatusCondition sets a status condition of the AppWrapper.
+// SetCondition sets a status condition of the AppWrapper.
 func (aw *AppWrapperWrapper) SetCondition(condition metav1.Condition) *AppWrapperWrapper {
 	meta.SetStatusCondition(&aw.Status.Conditions, condition)
 	return aw
diff --git a/pkg/util/testingjobs/deployment/wrappers.go b/pkg/util/testingjobs/deployment/wrappers.go
index 16af7af32..facd3e8b2 100644
--- a/pkg/util/testingjobs/deployment/wrappers.go
+++ b/pkg/util/testingjobs/deployment/wrappers.go
@@ -107,6 +107,20 @@ func (d *DeploymentWrapper) Request(r corev1.ResourceName, v string) *Deployment
 	return d
 }
 
+// Limit adds a resource limit to the default container.
+func (d *DeploymentWrapper) Limit(r corev1.ResourceName, v string) *DeploymentWrapper {
+	if d.Spec.Template.Spec.Containers[0].Resources.Limits == nil {
+		d.Spec.Template.Spec.Containers[0].Resources.Limits = corev1.ResourceList{}
+	}
+	d.Spec.Template.Spec.Containers[0].Resources.Limits[r] = resource.MustParse(v)
+	return d
+}
+
+// RequestAndLimit adds a resource request and limit to the default container.
+func (d *DeploymentWrapper) RequestAndLimit(r corev1.ResourceName, v string) *DeploymentWrapper {
+	return d.Request(r, v).Limit(r, v)
+}
+
 // Replicas updated the replicas of the Deployment
 func (d *DeploymentWrapper) Replicas(replicas int32) *DeploymentWrapper {
 	d.Spec.Replicas = &replicas
diff --git a/pkg/util/testingjobs/job/wrappers.go b/pkg/util/testingjobs/job/wrappers.go
index c4b08d9d4..5b4ac1cb2 100644
--- a/pkg/util/testingjobs/job/wrappers.go
+++ b/pkg/util/testingjobs/job/wrappers.go
@@ -186,6 +186,11 @@ func (j *JobWrapper) Limit(r corev1.ResourceName, v string) *JobWrapper {
 	return j
 }
 
+// RequestAndLimit adds a resource request and limit to the default container.
+func (j *JobWrapper) RequestAndLimit(r corev1.ResourceName, v string) *JobWrapper {
+	return j.Request(r, v).Limit(r, v)
+}
+
 func (j *JobWrapper) Image(image string, args []string) *JobWrapper {
 	j.Spec.Template.Spec.Containers[0].Image = image
 	j.Spec.Template.Spec.Containers[0].Args = args
diff --git a/pkg/util/testingjobs/jobset/wrappers.go b/pkg/util/testingjobs/jobset/wrappers.go
index f785c71c2..02c3e8559 100644
--- a/pkg/util/testingjobs/jobset/wrappers.go
+++ b/pkg/util/testingjobs/jobset/wrappers.go
@@ -154,6 +154,11 @@ func (j *JobSetWrapper) Limit(replicatedJobName string, r corev1.ResourceName, v
 	return j
 }
 
+// RequestAndLimit adds a resource request and limit to the first container of the target replicatedJob.
+func (j *JobSetWrapper) RequestAndLimit(replicatedJobName string, r corev1.ResourceName, v string) *JobSetWrapper {
+	return j.Request(replicatedJobName, r, v).Limit(replicatedJobName, r, v)
+}
+
 // PriorityClass updates JobSet priorityclass.
 func (j *JobSetWrapper) PriorityClass(pc string) *JobSetWrapper {
 	for i := range j.Spec.ReplicatedJobs {
diff --git a/pkg/util/testingjobs/leaderworkerset/wrappers.go b/pkg/util/testingjobs/leaderworkerset/wrappers.go
index 646ea989d..45c22f14d 100644
--- a/pkg/util/testingjobs/leaderworkerset/wrappers.go
+++ b/pkg/util/testingjobs/leaderworkerset/wrappers.go
@@ -186,6 +186,11 @@ func (w *LeaderWorkerSetWrapper) Limit(r corev1.ResourceName, v string) *LeaderW
 	return w
 }
 
+// RequestAndLimit adds a resource request and limit to the default container.
+func (w *LeaderWorkerSetWrapper) RequestAndLimit(r corev1.ResourceName, v string) *LeaderWorkerSetWrapper {
+	return w.Request(r, v).Limit(r, v)
+}
+
 // LeaderTemplate sets the leader template of the LeaderWorkerSet.
 func (w *LeaderWorkerSetWrapper) LeaderTemplate(leader corev1.PodTemplateSpec) *LeaderWorkerSetWrapper {
 	w.Spec.LeaderWorkerTemplate.LeaderTemplate = &leader
diff --git a/pkg/util/testingjobs/mpijob/wrappers_mpijob.go b/pkg/util/testingjobs/mpijob/wrappers_mpijob.go
index 0ec4b6f32..afc85ab6a 100644
--- a/pkg/util/testingjobs/mpijob/wrappers_mpijob.go
+++ b/pkg/util/testingjobs/mpijob/wrappers_mpijob.go
@@ -178,6 +178,11 @@ func (j *MPIJobWrapper) Limit(replicaType kfmpi.MPIReplicaType, r corev1.Resourc
 	return j
 }
 
+// RequestAndLimit adds a resource request and limit to the default container.
+func (j *MPIJobWrapper) RequestAndLimit(replicaType kfmpi.MPIReplicaType, r corev1.ResourceName, v string) *MPIJobWrapper {
+	return j.Request(replicaType, r, v).Limit(replicaType, r, v)
+}
+
 // Parallelism updates job parallelism.
 func (j *MPIJobWrapper) Parallelism(p int32) *MPIJobWrapper {
 	j.Spec.MPIReplicaSpecs[kfmpi.MPIReplicaTypeWorker].Replicas = ptr.To(p)
diff --git a/pkg/util/testingjobs/pod/wrappers.go b/pkg/util/testingjobs/pod/wrappers.go
index 81b739aad..6f168adc7 100644
--- a/pkg/util/testingjobs/pod/wrappers.go
+++ b/pkg/util/testingjobs/pod/wrappers.go
@@ -221,6 +221,11 @@ func (p *PodWrapper) Request(r corev1.ResourceName, v string) *PodWrapper {
 	return p
 }
 
+// RequestAndLimit adds a resource request and limit to the default container.
+func (p *PodWrapper) RequestAndLimit(r corev1.ResourceName, v string) *PodWrapper {
+	return p.Request(r, v).Limit(r, v)
+}
+
 func (p *PodWrapper) ServiceAccountName(serviceAccountName string) *PodWrapper {
 	p.Spec.ServiceAccountName = serviceAccountName
 	return p
diff --git a/pkg/util/testingjobs/pytorchjob/wrappers_pytorchjob.go b/pkg/util/testingjobs/pytorchjob/wrappers_pytorchjob.go
index 93889e655..353edca10 100644
--- a/pkg/util/testingjobs/pytorchjob/wrappers_pytorchjob.go
+++ b/pkg/util/testingjobs/pytorchjob/wrappers_pytorchjob.go
@@ -179,6 +179,11 @@ func (j *PyTorchJobWrapper) Limit(replicaType kftraining.ReplicaType, r corev1.R
 	return j
 }
 
+// RequestAndLimit adds a resource request and limit to the default container.
+func (j *PyTorchJobWrapper) RequestAndLimit(replicaType kftraining.ReplicaType, r corev1.ResourceName, v string) *PyTorchJobWrapper {
+	return j.Request(replicaType, r, v).Limit(replicaType, r, v)
+}
+
 // Parallelism updates job parallelism.
 func (j *PyTorchJobWrapper) Parallelism(p int32) *PyTorchJobWrapper {
 	j.Spec.PyTorchReplicaSpecs[kftraining.PyTorchJobReplicaTypeWorker].Replicas = ptr.To(p)
@@ -215,7 +220,7 @@ func (j *PyTorchJobWrapper) PodLabel(replicaType kftraining.ReplicaType, k, v st
 	return j
 }
 
-// Condition adds a condition
+// StatusConditions adds a condition.
 func (j *PyTorchJobWrapper) StatusConditions(c kftraining.JobCondition) *PyTorchJobWrapper {
 	j.Status.Conditions = append(j.Status.Conditions, c)
 	return j
diff --git a/pkg/util/testingjobs/raycluster/wrappers.go b/pkg/util/testingjobs/raycluster/wrappers.go
index b91b3a055..e47f73254 100644
--- a/pkg/util/testingjobs/raycluster/wrappers.go
+++ b/pkg/util/testingjobs/raycluster/wrappers.go
@@ -210,6 +210,21 @@ func (j *ClusterWrapper) Request(rayType rayv1.RayNodeType, r corev1.ResourceNam
 	return j
 }
 
+// Limit adds a resource limit to the default container.
+func (j *ClusterWrapper) Limit(rayType rayv1.RayNodeType, r corev1.ResourceName, v string) *ClusterWrapper {
+	if rayType == rayv1.HeadNode {
+		j.Spec.HeadGroupSpec.Template.Spec.Containers[0].Resources.Limits[r] = resource.MustParse(v)
+	} else if rayType == rayv1.WorkerNode {
+		j.Spec.WorkerGroupSpecs[0].Template.Spec.Containers[0].Resources.Limits[r] = resource.MustParse(v)
+	}
+	return j
+}
+
+// RequestAndLimit adds a resource request and limit to the default container.
+func (j *ClusterWrapper) RequestAndLimit(rayType rayv1.RayNodeType, r corev1.ResourceName, v string) *ClusterWrapper {
+	return j.Request(rayType, r, v).Limit(rayType, r, v)
+}
+
 func (j *ClusterWrapper) Image(rayType rayv1.RayNodeType, image string, args []string) *ClusterWrapper {
 	if rayType == rayv1.HeadNode {
 		j.Spec.HeadGroupSpec.Template.Spec.Containers[0].Image = image
diff --git a/pkg/util/testingjobs/rayjob/wrappers.go b/pkg/util/testingjobs/rayjob/wrappers.go
index 703001245..a0f3e0f25 100644
--- a/pkg/util/testingjobs/rayjob/wrappers.go
+++ b/pkg/util/testingjobs/rayjob/wrappers.go
@@ -227,6 +227,21 @@ func (j *JobWrapper) Request(rayType rayv1.RayNodeType, r corev1.ResourceName, v
 	return j
 }
 
+// Limit adds a resource request to the default container.
+func (j *JobWrapper) Limit(rayType rayv1.RayNodeType, r corev1.ResourceName, v string) *JobWrapper {
+	if rayType == rayv1.HeadNode {
+		j.Spec.RayClusterSpec.HeadGroupSpec.Template.Spec.Containers[0].Resources.Limits[r] = resource.MustParse(v)
+	} else if rayType == rayv1.WorkerNode {
+		j.Spec.RayClusterSpec.WorkerGroupSpecs[0].Template.Spec.Containers[0].Resources.Limits[r] = resource.MustParse(v)
+	}
+	return j
+}
+
+// RequestAndLimit adds a resource request and limit to the default container.
+func (j *JobWrapper) RequestAndLimit(rayType rayv1.RayNodeType, r corev1.ResourceName, v string) *JobWrapper {
+	return j.Request(rayType, r, v).Limit(rayType, r, v)
+}
+
 func (j *JobWrapper) Image(rayType rayv1.RayNodeType, image string, args ...string) *JobWrapper {
 	if rayType == rayv1.HeadNode {
 		j.Spec.RayClusterSpec.HeadGroupSpec.Template.Spec.Containers[0].Image = image
diff --git a/pkg/util/testingjobs/statefulset/wrappers.go b/pkg/util/testingjobs/statefulset/wrappers.go
index ee5efae70..f28c168b9 100644
--- a/pkg/util/testingjobs/statefulset/wrappers.go
+++ b/pkg/util/testingjobs/statefulset/wrappers.go
@@ -210,3 +210,8 @@ func (ss *StatefulSetWrapper) Limit(r corev1.ResourceName, v string) *StatefulSe
 	ss.Spec.Template.Spec.Containers[0].Resources.Limits[r] = resource.MustParse(v)
 	return ss
 }
+
+// RequestAndLimit adds a resource request and limit to the default container.
+func (ss *StatefulSetWrapper) RequestAndLimit(r corev1.ResourceName, v string) *StatefulSetWrapper {
+	return ss.Request(r, v).Limit(r, v)
+}
diff --git a/pkg/util/testingjobs/tfjob/wrappers_tfjob.go b/pkg/util/testingjobs/tfjob/wrappers_tfjob.go
index 0be631510..fa1ad081c 100644
--- a/pkg/util/testingjobs/tfjob/wrappers_tfjob.go
+++ b/pkg/util/testingjobs/tfjob/wrappers_tfjob.go
@@ -200,7 +200,7 @@ func (j *TFJobWrapper) UID(uid string) *TFJobWrapper {
 	return j
 }
 
-// Condition adds a condition
+// StatusConditions adds a condition.
 func (j *TFJobWrapper) StatusConditions(c kftraining.JobCondition) *TFJobWrapper {
 	j.Status.Conditions = append(j.Status.Conditions, c)
 	return j
diff --git a/test/OWNERS b/test/OWNERS
index f8fdba0e9..497236848 100644
--- a/test/OWNERS
+++ b/test/OWNERS
@@ -1,4 +1,7 @@
 # See the OWNERS docs at https://go.k8s.io/owners
 
+reviewers:
+- kannon92
+
 emeritus_approvers:
 - trasc
diff --git a/test/e2e/customconfigs/skipjobswithoutqueuename_test.go b/test/e2e/customconfigs/skipjobswithoutqueuename_test.go
index 63832d94c..b7a2cde53 100644
--- a/test/e2e/customconfigs/skipjobswithoutqueuename_test.go
+++ b/test/e2e/customconfigs/skipjobswithoutqueuename_test.go
@@ -83,6 +83,7 @@ var _ = ginkgo.Describe("ManageJobsWithoutQueueName", ginkgo.Ordered, func() {
 		gomega.Expect(util.DeleteNamespace(ctx, k8sClient, ns)).To(gomega.Succeed())
 		util.ExpectObjectToBeDeletedWithTimeout(ctx, k8sClient, clusterQueue, true, util.LongTimeout)
 		util.ExpectObjectToBeDeletedWithTimeout(ctx, k8sClient, defaultRf, true, util.LongTimeout)
+		util.ExpectAllPodsInNamespaceDeleted(ctx, k8sClient, ns)
 	})
 	ginkgo.When("manageJobsWithoutQueueName=true", func() {
 		ginkgo.It("should suspend a job", func() {
@@ -130,7 +131,7 @@ var _ = ginkgo.Describe("ManageJobsWithoutQueueName", ginkgo.Ordered, func() {
 			numPods := 2
 			aw := awtesting.MakeAppWrapper("aw-child", ns.Name).
 				Component(testingjob.MakeJob("job-0", ns.Name).
-					Request(corev1.ResourceCPU, "100m").
+					RequestAndLimit(corev1.ResourceCPU, "200m").
 					Parallelism(int32(numPods)).
 					Completions(int32(numPods)).
 					Suspend(false).
@@ -193,7 +194,7 @@ var _ = ginkgo.Describe("ManageJobsWithoutQueueName", ginkgo.Ordered, func() {
 					).
 					SetTypeMeta().
 					Suspend(false).
-					Request("replicated-job-1", corev1.ResourceCPU, "100m").
+					RequestAndLimit("replicated-job-1", corev1.ResourceCPU, "200m").
 					Obj()).
 				Suspend(false).
 				Obj()
@@ -265,8 +266,8 @@ var _ = ginkgo.Describe("ManageJobsWithoutQueueName", ginkgo.Ordered, func() {
 			ginkgo.By("creating a pod without a queue name", func() {
 				testPod = testingpod.MakePod("test-pod", "kube-system").
 					Image(util.E2eTestAgnHostImage, util.BehaviorWaitForDeletion).
-					Request(corev1.ResourceCPU, "1").
-					Request(corev1.ResourceMemory, "2Gi").
+					RequestAndLimit(corev1.ResourceCPU, "1").
+					RequestAndLimit(corev1.ResourceMemory, "2Gi").
 					Obj()
 				gomega.Expect(k8sClient.Create(ctx, testPod)).Should(gomega.Succeed())
 			})
@@ -293,8 +294,8 @@ var _ = ginkgo.Describe("ManageJobsWithoutQueueName", ginkgo.Ordered, func() {
 			ginkgo.By("creating a deployment without a queue name", func() {
 				testDeploy = testingdeploy.MakeDeployment("test-deploy", ns.Name).
 					Image(util.E2eTestAgnHostImage, util.BehaviorWaitForDeletion).
-					Request(corev1.ResourceCPU, "1").
-					Request(corev1.ResourceMemory, "2Gi").
+					RequestAndLimit(corev1.ResourceCPU, "1").
+					RequestAndLimit(corev1.ResourceMemory, "2Gi").
 					Replicas(2).
 					Obj()
 				gomega.Expect(k8sClient.Create(ctx, testDeploy)).Should(gomega.Succeed())
@@ -322,8 +323,8 @@ var _ = ginkgo.Describe("ManageJobsWithoutQueueName", ginkgo.Ordered, func() {
 			ginkgo.By("creating a deployment without a queue name in the kube-system namespace", func() {
 				testDeploy = testingdeploy.MakeDeployment("test-deploy", "kube-system").
 					Image(util.E2eTestAgnHostImage, util.BehaviorWaitForDeletion).
-					Request(corev1.ResourceCPU, "1").
-					Request(corev1.ResourceMemory, "2Gi").
+					RequestAndLimit(corev1.ResourceCPU, "1").
+					RequestAndLimit(corev1.ResourceMemory, "2Gi").
 					Replicas(2).
 					Obj()
 				gomega.Expect(k8sClient.Create(ctx, testDeploy)).Should(gomega.Succeed())
@@ -357,8 +358,8 @@ var _ = ginkgo.Describe("ManageJobsWithoutQueueName", ginkgo.Ordered, func() {
 			ginkgo.By("creating a StatefulSet without a queue name", func() {
 				testSts = testingsts.MakeStatefulSet("test-sts", ns.Name).
 					Image(util.E2eTestAgnHostImage, util.BehaviorWaitForDeletion).
-					Request(corev1.ResourceCPU, "1").
-					Request(corev1.ResourceMemory, "2Gi").
+					RequestAndLimit(corev1.ResourceCPU, "1").
+					RequestAndLimit(corev1.ResourceMemory, "2Gi").
 					Replicas(2).
 					Obj()
 				gomega.Expect(k8sClient.Create(ctx, testSts)).Should(gomega.Succeed())
@@ -387,8 +388,8 @@ var _ = ginkgo.Describe("ManageJobsWithoutQueueName", ginkgo.Ordered, func() {
 			ginkgo.By("creating a StatefulSet without a queue name in the kube-system namespace", func() {
 				testSts = testingsts.MakeStatefulSet("test-sts", "kube-system").
 					Image(util.E2eTestAgnHostImage, util.BehaviorWaitForDeletion).
-					Request(corev1.ResourceCPU, "1").
-					Request(corev1.ResourceMemory, "2Gi").
+					RequestAndLimit(corev1.ResourceCPU, "1").
+					RequestAndLimit(corev1.ResourceMemory, "2Gi").
 					Replicas(2).
 					Obj()
 				gomega.Expect(k8sClient.Create(ctx, testSts)).Should(gomega.Succeed())
diff --git a/test/e2e/customconfigs/suite_test.go b/test/e2e/customconfigs/suite_test.go
index 04f847098..5456f4765 100644
--- a/test/e2e/customconfigs/suite_test.go
+++ b/test/e2e/customconfigs/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,7 +49,7 @@ func TestAPIs(t *testing.T) {
 }
 
 var _ = ginkgo.BeforeSuite(func() {
-	ctrl.SetLogger(util.NewTestingLogger(ginkgo.GinkgoWriter, -3))
+	util.SetupLogger()
 
 	k8sClient, _ = util.CreateClientUsingCluster("")
 	ctx = context.Background()
diff --git a/test/e2e/multikueue/e2e_test.go b/test/e2e/multikueue/e2e_test.go
index 390369b29..ee2d83aea 100644
--- a/test/e2e/multikueue/e2e_test.go
+++ b/test/e2e/multikueue/e2e_test.go
@@ -199,14 +199,18 @@ var _ = ginkgo.Describe("MultiKueue", func() {
 		util.ExpectObjectToBeDeleted(ctx, k8sManagerClient, multiKueueConfig, true)
 		util.ExpectObjectToBeDeleted(ctx, k8sManagerClient, workerCluster1, true)
 		util.ExpectObjectToBeDeleted(ctx, k8sManagerClient, workerCluster2, true)
+
+		util.ExpectAllPodsInNamespaceDeleted(ctx, k8sManagerClient, managerNs)
+		util.ExpectAllPodsInNamespaceDeleted(ctx, k8sWorker1Client, worker1Ns)
+		util.ExpectAllPodsInNamespaceDeleted(ctx, k8sWorker2Client, worker2Ns)
 	})
 
 	ginkgo.When("Creating a multikueue admission check", func() {
 		ginkgo.It("Should create a pod on worker if admitted", func() {
 			pod := testingpod.MakePod("pod", managerNs.Name).
 				Image(util.E2eTestAgnHostImage, util.BehaviorExitFast).
-				Request("cpu", "1").
-				Request("memory", "2G").
+				RequestAndLimit("cpu", "1").
+				RequestAndLimit("memory", "2G").
 				Queue(managerLq.Name).
 				Obj()
 			// Since it requires 2G of memory, this pod can only be admitted in worker 2.
@@ -392,8 +396,8 @@ var _ = ginkgo.Describe("MultiKueue", func() {
 			// Since it requires 2G of memory, this job can only be admitted in worker 2.
 			job := testingjob.MakeJob("job", managerNs.Name).
 				Queue(managerLq.Name).
-				Request("cpu", "1").
-				Request("memory", "2G").
+				RequestAndLimit("cpu", "1").
+				RequestAndLimit("memory", "2G").
 				// Give it the time to be observed Active in the live status update step.
 				Image(util.E2eTestAgnHostImage, util.BehaviorWaitForDeletion).
 				Obj()
@@ -488,8 +492,8 @@ var _ = ginkgo.Describe("MultiKueue", func() {
 						Args: util.BehaviorWaitForDeletion,
 					},
 				).
-				Request("replicated-job-1", "cpu", "500m").
-				Request("replicated-job-1", "memory", "200M").
+				RequestAndLimit("replicated-job-1", "cpu", "500m").
+				RequestAndLimit("replicated-job-1", "memory", "200M").
 				Obj()
 
 			ginkgo.By("Creating the jobSet", func() {
@@ -582,7 +586,7 @@ var _ = ginkgo.Describe("MultiKueue", func() {
 					Suspend(false).
 					Image(util.E2eTestAgnHostImage, util.BehaviorWaitForDeletion). // Give it the time to be observed Active in the live status update step.
 					Parallelism(2).
-					Request(corev1.ResourceCPU, "1").
+					RequestAndLimit(corev1.ResourceCPU, "1").
 					SetTypeMeta().Obj()).
 				Obj()
 
@@ -655,10 +659,10 @@ var _ = ginkgo.Describe("MultiKueue", func() {
 						RestartPolicy: "OnFailure",
 					},
 				).
-				Request(kftraining.PyTorchJobReplicaTypeMaster, corev1.ResourceCPU, "0.2").
-				Request(kftraining.PyTorchJobReplicaTypeMaster, corev1.ResourceMemory, "800M").
-				Request(kftraining.PyTorchJobReplicaTypeWorker, corev1.ResourceCPU, "0.5").
-				Request(kftraining.PyTorchJobReplicaTypeWorker, corev1.ResourceMemory, "800M").
+				RequestAndLimit(kftraining.PyTorchJobReplicaTypeMaster, corev1.ResourceCPU, "0.2").
+				RequestAndLimit(kftraining.PyTorchJobReplicaTypeMaster, corev1.ResourceMemory, "800M").
+				RequestAndLimit(kftraining.PyTorchJobReplicaTypeWorker, corev1.ResourceCPU, "0.5").
+				RequestAndLimit(kftraining.PyTorchJobReplicaTypeWorker, corev1.ResourceMemory, "800M").
 				Image(kftraining.PyTorchJobReplicaTypeMaster, util.E2eTestAgnHostImage, util.BehaviorExitFast).
 				Image(kftraining.PyTorchJobReplicaTypeWorker, util.E2eTestAgnHostImage, util.BehaviorExitFast).
 				Obj()
@@ -718,10 +722,10 @@ var _ = ginkgo.Describe("MultiKueue", func() {
 						RestartPolicy: "OnFailure",
 					},
 				).
-				Request(kfmpi.MPIReplicaTypeLauncher, corev1.ResourceCPU, "1").
-				Request(kfmpi.MPIReplicaTypeLauncher, corev1.ResourceMemory, "200M").
-				Request(kfmpi.MPIReplicaTypeWorker, corev1.ResourceCPU, "0.5").
-				Request(kfmpi.MPIReplicaTypeWorker, corev1.ResourceMemory, "100M").
+				RequestAndLimit(kfmpi.MPIReplicaTypeLauncher, corev1.ResourceCPU, "1").
+				RequestAndLimit(kfmpi.MPIReplicaTypeLauncher, corev1.ResourceMemory, "200M").
+				RequestAndLimit(kfmpi.MPIReplicaTypeWorker, corev1.ResourceCPU, "0.5").
+				RequestAndLimit(kfmpi.MPIReplicaTypeWorker, corev1.ResourceMemory, "100M").
 				Image(kfmpi.MPIReplicaTypeLauncher, util.E2eTestAgnHostImage, util.BehaviorExitFast).
 				Image(kfmpi.MPIReplicaTypeWorker, util.E2eTestAgnHostImage, util.BehaviorExitFast).
 				Obj()
@@ -770,8 +774,8 @@ var _ = ginkgo.Describe("MultiKueue", func() {
 				Suspend(true).
 				Queue(managerLq.Name).
 				WithSubmissionMode(rayv1.K8sJobMode).
-				Request(rayv1.HeadNode, corev1.ResourceCPU, "1").
-				Request(rayv1.WorkerNode, corev1.ResourceCPU, "0.5").
+				RequestAndLimit(rayv1.HeadNode, corev1.ResourceCPU, "1").
+				RequestAndLimit(rayv1.WorkerNode, corev1.ResourceCPU, "0.5").
 				Entrypoint("python -c \"import ray; ray.init(); print(ray.cluster_resources())\"").
 				Image(rayv1.HeadNode, kuberayTestImage).
 				Image(rayv1.WorkerNode, kuberayTestImage).
@@ -813,8 +817,8 @@ var _ = ginkgo.Describe("MultiKueue", func() {
 			raycluster := testingraycluster.MakeCluster("raycluster1", managerNs.Name).
 				Suspend(true).
 				Queue(managerLq.Name).
-				Request(rayv1.HeadNode, corev1.ResourceCPU, "1").
-				Request(rayv1.WorkerNode, corev1.ResourceCPU, "0.5").
+				RequestAndLimit(rayv1.HeadNode, corev1.ResourceCPU, "1").
+				RequestAndLimit(rayv1.WorkerNode, corev1.ResourceCPU, "0.5").
 				Image(rayv1.HeadNode, kuberayTestImage, []string{}).
 				Image(rayv1.WorkerNode, kuberayTestImage, []string{}).
 				Obj()
diff --git a/test/e2e/multikueue/suite_test.go b/test/e2e/multikueue/suite_test.go
index 2c560cc56..273cef599 100644
--- a/test/e2e/multikueue/suite_test.go
+++ b/test/e2e/multikueue/suite_test.go
@@ -40,7 +40,6 @@ import (
 	"k8s.io/client-go/tools/clientcmd"
 	clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
 	"k8s.io/utils/ptr"
-	ctrl "sigs.k8s.io/controller-runtime"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 	jobset "sigs.k8s.io/jobset/api/jobset/v1alpha2"
 
@@ -249,7 +248,7 @@ func TestAPIs(t *testing.T) {
 }
 
 var _ = ginkgo.BeforeSuite(func() {
-	ctrl.SetLogger(util.NewTestingLogger(ginkgo.GinkgoWriter, -3))
+	util.SetupLogger()
 
 	managerClusterName = os.Getenv("MANAGER_KIND_CLUSTER_NAME")
 	gomega.Expect(managerClusterName).NotTo(gomega.BeEmpty(), "MANAGER_KIND_CLUSTER_NAME should not be empty")
diff --git a/test/e2e/singlecluster/appwrapper_test.go b/test/e2e/singlecluster/appwrapper_test.go
index 65f3bc16c..b03bbfc49 100644
--- a/test/e2e/singlecluster/appwrapper_test.go
+++ b/test/e2e/singlecluster/appwrapper_test.go
@@ -77,13 +77,14 @@ var _ = ginkgo.Describe("AppWrapper", func() {
 		gomega.Expect(util.DeleteNamespace(ctx, k8sClient, ns)).To(gomega.Succeed())
 		util.ExpectObjectToBeDeleted(ctx, k8sClient, cq, true)
 		util.ExpectObjectToBeDeleted(ctx, k8sClient, rf, true)
+		util.ExpectAllPodsInNamespaceDeleted(ctx, k8sClient, ns)
 	})
 
 	ginkgo.It("Should admit workloads that fit", func() {
 		numPods := 2
 		aw := awtesting.MakeAppWrapper("appwrapper", ns.Name).
 			Component(utiltestingjob.MakeJob("job-0", ns.Name).
-				Request(corev1.ResourceCPU, "100m").
+				RequestAndLimit(corev1.ResourceCPU, "200m").
 				Parallelism(int32(numPods)).
 				Completions(int32(numPods)).
 				Suspend(false).
diff --git a/test/e2e/singlecluster/deployment_test.go b/test/e2e/singlecluster/deployment_test.go
index 7c4bbd4a3..c0056de7d 100644
--- a/test/e2e/singlecluster/deployment_test.go
+++ b/test/e2e/singlecluster/deployment_test.go
@@ -81,12 +81,13 @@ var _ = ginkgo.Describe("Deployment", func() {
 		gomega.Expect(util.DeleteNamespace(ctx, k8sClient, ns)).To(gomega.Succeed())
 		util.ExpectObjectToBeDeleted(ctx, k8sClient, cq, true)
 		util.ExpectObjectToBeDeleted(ctx, k8sClient, rf, true)
+		util.ExpectAllPodsInNamespaceDeleted(ctx, k8sClient, ns)
 	})
 
 	ginkgo.It("should admit workloads that fits", func() {
 		deployment := deploymenttesting.MakeDeployment("deployment", ns.Name).
 			Image(util.E2eTestAgnHostImage, util.BehaviorWaitForDeletion).
-			Request(corev1.ResourceCPU, "100m").
+			RequestAndLimit(corev1.ResourceCPU, "200m").
 			Replicas(3).
 			Queue(lq.Name).
 			Obj()
@@ -135,7 +136,7 @@ var _ = ginkgo.Describe("Deployment", func() {
 	ginkgo.It("should admit workloads after change queue-name if AvailableReplicas = 0", func() {
 		deployment := deploymenttesting.MakeDeployment("deployment", ns.Name).
 			Image(util.E2eTestAgnHostImage, util.BehaviorWaitForDeletion).
-			Request(corev1.ResourceCPU, "100m").
+			RequestAndLimit(corev1.ResourceCPU, "200m").
 			Replicas(3).
 			Queue("invalid-queue-name").
 			Obj()
diff --git a/test/e2e/singlecluster/e2e_test.go b/test/e2e/singlecluster/e2e_test.go
index 6547eb69e..543245b23 100644
--- a/test/e2e/singlecluster/e2e_test.go
+++ b/test/e2e/singlecluster/e2e_test.go
@@ -51,13 +51,14 @@ var _ = ginkgo.Describe("Kueue", func() {
 		gomega.Expect(k8sClient.Create(ctx, ns)).To(gomega.Succeed())
 		sampleJob = testingjob.MakeJob("test-job", ns.Name).
 			Queue("main").
-			Request("cpu", "1").
-			Request("memory", "20Mi").
+			RequestAndLimit("cpu", "1").
+			RequestAndLimit("memory", "20Mi").
 			Obj()
 		jobKey = client.ObjectKeyFromObject(sampleJob)
 	})
 	ginkgo.AfterEach(func() {
 		gomega.Expect(util.DeleteNamespace(ctx, k8sClient, ns)).To(gomega.Succeed())
+		util.ExpectAllPodsInNamespaceDeleted(ctx, k8sClient, ns)
 	})
 
 	ginkgo.When("Creating a Job without a matching LocalQueue", func() {
@@ -120,6 +121,7 @@ var _ = ginkgo.Describe("Kueue", func() {
 			util.ExpectObjectToBeDeleted(ctx, k8sClient, clusterQueue, true)
 			util.ExpectObjectToBeDeleted(ctx, k8sClient, onDemandRF, true)
 			util.ExpectObjectToBeDeleted(ctx, k8sClient, spotRF, true)
+			util.ExpectAllPodsInNamespaceDeleted(ctx, k8sClient, ns)
 		})
 
 		ginkgo.It("Should unsuspend a job and set nodeSelectors", func() {
@@ -232,7 +234,7 @@ var _ = ginkgo.Describe("Kueue", func() {
 				job := testingjob.MakeJob("high", ns.Name).
 					Queue("main").
 					PriorityClass("high").
-					Request(corev1.ResourceCPU, "1").
+					RequestAndLimit(corev1.ResourceCPU, "1").
 					NodeSelector("instance-type", "on-demand"). // target the same flavor to cause preemption
 					Obj()
 				gomega.Expect(k8sClient.Create(ctx, job)).Should(gomega.Succeed())
@@ -268,7 +270,7 @@ var _ = ginkgo.Describe("Kueue", func() {
 				job := testingjob.MakeJob("high-with-wpc", ns.Name).
 					Queue("main").
 					WorkloadPriorityClass("high-workload").
-					Request(corev1.ResourceCPU, "1").
+					RequestAndLimit(corev1.ResourceCPU, "1").
 					NodeSelector("instance-type", "on-demand"). // target the same flavor to cause preemption
 					Obj()
 				gomega.Expect(k8sClient.Create(ctx, job)).Should(gomega.Succeed())
@@ -289,7 +291,7 @@ var _ = ginkgo.Describe("Kueue", func() {
 			job := testingjob.MakeJob("job", ns.Name).
 				Queue("main").
 				Image(util.E2eTestAgnHostImage, util.BehaviorExitFast).
-				Request("cpu", "500m").
+				RequestAndLimit("cpu", "500m").
 				Parallelism(3).
 				Completions(4).
 				SetAnnotation(workloadjob.JobMinParallelismAnnotation, "1").
@@ -358,6 +360,7 @@ var _ = ginkgo.Describe("Kueue", func() {
 			util.ExpectObjectToBeDeleted(ctx, k8sClient, clusterQueue, true)
 			util.ExpectObjectToBeDeleted(ctx, k8sClient, onDemandRF, true)
 			util.ExpectObjectToBeDeleted(ctx, k8sClient, check, true)
+			util.ExpectAllPodsInNamespaceDeleted(ctx, k8sClient, ns)
 		})
 
 		ginkgo.It("Should unsuspend a job only after all checks are cleared", func() {
diff --git a/test/e2e/singlecluster/fair_sharing_test.go b/test/e2e/singlecluster/fair_sharing_test.go
index e8c483097..703ba43da 100644
--- a/test/e2e/singlecluster/fair_sharing_test.go
+++ b/test/e2e/singlecluster/fair_sharing_test.go
@@ -89,6 +89,7 @@ var _ = ginkgo.Describe("Fair Sharing", ginkgo.Ordered, ginkgo.ContinueOnFailure
 		util.ExpectObjectToBeDeleted(ctx, k8sClient, cq2, true)
 		util.ExpectObjectToBeDeleted(ctx, k8sClient, cq3, true)
 		util.ExpectObjectToBeDeleted(ctx, k8sClient, rf, true)
+		util.ExpectAllPodsInNamespaceDeleted(ctx, k8sClient, ns)
 	})
 
 	ginkgo.When("the cluster queue starts borrowing", func() {
@@ -100,8 +101,8 @@ var _ = ginkgo.Describe("Fair Sharing", ginkgo.Ordered, ginkgo.ContinueOnFailure
 					Image(util.E2eTestAgnHostImage, util.BehaviorExitFast).
 					Parallelism(3).
 					Completions(3).
-					Request("cpu", "1").
-					Request("memory", "200Mi").
+					RequestAndLimit("cpu", "1").
+					RequestAndLimit("memory", "200Mi").
 					Obj()
 				gomega.Expect(k8sClient.Create(ctx, job)).To(gomega.Succeed())
 			}
diff --git a/test/e2e/singlecluster/jobset_test.go b/test/e2e/singlecluster/jobset_test.go
index f8425c64c..6597135c6 100644
--- a/test/e2e/singlecluster/jobset_test.go
+++ b/test/e2e/singlecluster/jobset_test.go
@@ -47,6 +47,7 @@ var _ = ginkgo.Describe("JobSet", func() {
 	})
 	ginkgo.AfterEach(func() {
 		gomega.Expect(util.DeleteNamespace(ctx, k8sClient, ns)).To(gomega.Succeed())
+		util.ExpectAllPodsInNamespaceDeleted(ctx, k8sClient, ns)
 	})
 	ginkgo.When("Creating a JobSet", func() {
 		var (
@@ -73,6 +74,7 @@ var _ = ginkgo.Describe("JobSet", func() {
 			gomega.Expect(util.DeleteObject(ctx, k8sClient, localQueue)).Should(gomega.Succeed())
 			util.ExpectObjectToBeDeleted(ctx, k8sClient, clusterQueue, true)
 			util.ExpectObjectToBeDeleted(ctx, k8sClient, defaultRf, true)
+			util.ExpectAllPodsInNamespaceDeleted(ctx, k8sClient, ns)
 		})
 
 		ginkgo.It("Should run a jobSet if admitted", func() {
@@ -88,8 +90,8 @@ var _ = ginkgo.Describe("JobSet", func() {
 						Completions: 2,
 					},
 				).
-				Request("replicated-job-1", "cpu", "500m").
-				Request("replicated-job-1", "memory", "200M").
+				RequestAndLimit("replicated-job-1", "cpu", "500m").
+				RequestAndLimit("replicated-job-1", "memory", "200M").
 				Obj()
 
 			ginkgo.By("Creating the jobSet", func() {
@@ -154,6 +156,7 @@ var _ = ginkgo.Describe("JobSet", func() {
 			util.ExpectObjectToBeDeleted(ctx, k8sClient, clusterQueue, true)
 			util.ExpectObjectToBeDeleted(ctx, k8sClient, onDemandRF, true)
 			util.ExpectObjectToBeDeleted(ctx, k8sClient, spotRF, true)
+			util.ExpectAllPodsInNamespaceDeleted(ctx, k8sClient, ns)
 		})
 
 		ginkgo.It("Should allow to suspend a JobSet when injected nodeSelector", func() {
@@ -169,8 +172,8 @@ var _ = ginkgo.Describe("JobSet", func() {
 						Completions: 1,
 					},
 				).
-				Request("replicated-job-1", "cpu", "500m").
-				Request("replicated-job-1", "memory", "200M").
+				RequestAndLimit("replicated-job-1", "cpu", "500m").
+				RequestAndLimit("replicated-job-1", "memory", "200M").
 				Obj()
 
 			ginkgo.By("Creating the jobSet", func() {
diff --git a/test/e2e/singlecluster/kueuectl_test.go b/test/e2e/singlecluster/kueuectl_test.go
index 954f85c7f..4e68cb66d 100644
--- a/test/e2e/singlecluster/kueuectl_test.go
+++ b/test/e2e/singlecluster/kueuectl_test.go
@@ -47,6 +47,7 @@ var _ = ginkgo.Describe("Kueuectl Create", ginkgo.Ordered, ginkgo.ContinueOnFail
 	ginkgo.AfterEach(func() {
 		gomega.Expect(util.DeleteNamespace(ctx, k8sClient, ns)).To(gomega.Succeed())
 		util.ExpectObjectToBeDeleted(ctx, k8sClient, cq, true)
+		util.ExpectAllPodsInNamespaceDeleted(ctx, k8sClient, ns)
 	})
 
 	ginkgo.When("Creating a LocalQueue", func() {
diff --git a/test/e2e/singlecluster/leaderworkerset_test.go b/test/e2e/singlecluster/leaderworkerset_test.go
index fc679c60d..c18e25aa5 100644
--- a/test/e2e/singlecluster/leaderworkerset_test.go
+++ b/test/e2e/singlecluster/leaderworkerset_test.go
@@ -79,6 +79,7 @@ var _ = ginkgo.Describe("LeaderWorkerSet integration", func() {
 		gomega.Expect(util.DeleteNamespace(ctx, k8sClient, ns)).To(gomega.Succeed())
 		util.ExpectObjectToBeDeleted(ctx, k8sClient, cq, true)
 		util.ExpectObjectToBeDeleted(ctx, k8sClient, rf, true)
+		util.ExpectAllPodsInNamespaceDeleted(ctx, k8sClient, ns)
 	})
 
 	ginkgo.When("LeaderWorkerSet created", func() {
@@ -87,7 +88,7 @@ var _ = ginkgo.Describe("LeaderWorkerSet integration", func() {
 				Image(util.E2eTestAgnHostImage, util.BehaviorWaitForDeletion).
 				Size(1).
 				Replicas(1).
-				Request(corev1.ResourceCPU, "100m").
+				RequestAndLimit(corev1.ResourceCPU, "200m").
 				Queue(lq.Name).
 				Obj()
 
@@ -145,7 +146,7 @@ var _ = ginkgo.Describe("LeaderWorkerSet integration", func() {
 				Image(util.E2eTestAgnHostImage, util.BehaviorWaitForDeletion).
 				Size(3).
 				Replicas(1).
-				Request(corev1.ResourceCPU, "100m").
+				RequestAndLimit(corev1.ResourceCPU, "200m").
 				Queue(lq.Name).
 				Obj()
 			ginkgo.By("Create a LeaderWorkerSet", func() {
@@ -199,7 +200,7 @@ var _ = ginkgo.Describe("LeaderWorkerSet integration", func() {
 				Image(util.E2eTestAgnHostImage, util.BehaviorWaitForDeletion).
 				Size(3).
 				Replicas(2).
-				Request(corev1.ResourceCPU, "100m").
+				RequestAndLimit(corev1.ResourceCPU, "200m").
 				Queue(lq.Name).
 				Obj()
 
@@ -262,7 +263,7 @@ var _ = ginkgo.Describe("LeaderWorkerSet integration", func() {
 					Image(util.E2eTestAgnHostImage, util.BehaviorWaitForDeletion).
 					Size(3).
 					Replicas(1).
-					Request(corev1.ResourceCPU, "100m").
+					RequestAndLimit(corev1.ResourceCPU, "200m").
 					Queue(lq.Name).
 					StartupPolicy(startupPolicyType).
 					Obj()
@@ -356,7 +357,7 @@ var _ = ginkgo.Describe("LeaderWorkerSet integration", func() {
 					Image(util.E2eTestAgnHostImage, util.BehaviorWaitForDeletion).
 					Size(3).
 					Replicas(2).
-					Request(corev1.ResourceCPU, "100m").
+					RequestAndLimit(corev1.ResourceCPU, "200m").
 					Queue(lq.Name).
 					StartupPolicy(startupPolicyType).
 					Obj()
@@ -453,7 +454,7 @@ var _ = ginkgo.Describe("LeaderWorkerSet integration", func() {
 					Image(util.E2eTestAgnHostImage, util.BehaviorWaitForDeletion).
 					Size(3).
 					Replicas(2).
-					Request(corev1.ResourceCPU, "100m").
+					RequestAndLimit(corev1.ResourceCPU, "200m").
 					Queue(lq.Name).
 					LeaderTemplate(corev1.PodTemplateSpec{
 						Spec: corev1.PodSpec{
@@ -536,7 +537,7 @@ var _ = ginkgo.Describe("LeaderWorkerSet integration", func() {
 				Image(util.E2eTestAgnHostImageOld, util.BehaviorWaitForDeletion).
 				Size(3).
 				Replicas(2).
-				Request(corev1.ResourceCPU, "100m").
+				RequestAndLimit(corev1.ResourceCPU, "200m").
 				Queue(lq.Name).
 				LeaderTemplate(corev1.PodTemplateSpec{
 					Spec: corev1.PodSpec{
diff --git a/test/e2e/singlecluster/metrics_test.go b/test/e2e/singlecluster/metrics_test.go
index b0d4cf431..7bfa873b3 100644
--- a/test/e2e/singlecluster/metrics_test.go
+++ b/test/e2e/singlecluster/metrics_test.go
@@ -100,11 +100,10 @@ var _ = ginkgo.Describe("Metrics", func() {
 
 	ginkgo.AfterEach(func() {
 		gomega.Expect(util.DeleteNamespace(ctx, k8sClient, ns)).To(gomega.Succeed())
-
 		util.ExpectObjectToBeDeleted(ctx, k8sClient, resourceFlavor, true)
-
 		util.ExpectObjectToBeDeleted(ctx, k8sClient, metricsReaderClusterRoleBinding, true)
 		util.ExpectObjectToBeDeletedWithTimeout(ctx, k8sClient, curlPod, true, util.LongTimeout)
+		util.ExpectAllPodsInNamespaceDeleted(ctx, k8sClient, ns)
 	})
 
 	ginkgo.When("workload is admitted", func() {
@@ -137,7 +136,7 @@ var _ = ginkgo.Describe("Metrics", func() {
 				PodSets(
 					*utiltesting.MakePodSet("ps1", 1).Obj(),
 				).
-				Request(corev1.ResourceCPU, "1").
+				RequestAndLimit(corev1.ResourceCPU, "1").
 				Obj()
 			gomega.Expect(k8sClient.Create(ctx, workload)).To(gomega.Succeed())
 		})
@@ -269,7 +268,7 @@ var _ = ginkgo.Describe("Metrics", func() {
 
 			createdJob = testingjob.MakeJob("admission-checked-job", ns.Name).
 				Queue(localQueue.Name).
-				Request("cpu", "1").
+				RequestAndLimit("cpu", "1").
 				Obj()
 			gomega.Expect(k8sClient.Create(ctx, createdJob)).To(gomega.Succeed())
 
@@ -413,7 +412,7 @@ var _ = ginkgo.Describe("Metrics", func() {
 
 			lowerJob1 = testingjob.MakeJob("lower-job-1", ns.Name).
 				Queue(localQueue1.Name).
-				Request("cpu", "1").
+				RequestAndLimit("cpu", "1").
 				Obj()
 			gomega.Expect(k8sClient.Create(ctx, lowerJob1)).To(gomega.Succeed())
 
@@ -432,7 +431,7 @@ var _ = ginkgo.Describe("Metrics", func() {
 
 			lowerJob2 = testingjob.MakeJob("lower-job-2", ns.Name).
 				Queue(localQueue1.Name).
-				Request("cpu", "1").
+				RequestAndLimit("cpu", "1").
 				Obj()
 			gomega.Expect(k8sClient.Create(ctx, lowerJob2)).To(gomega.Succeed())
 
@@ -452,7 +451,7 @@ var _ = ginkgo.Describe("Metrics", func() {
 			blockerJob = testingjob.MakeJob("blocker", ns.Name).
 				Queue(localQueue2.Name).
 				PriorityClass(highPriorityClass.Name).
-				Request(corev1.ResourceCPU, "3").
+				RequestAndLimit(corev1.ResourceCPU, "3").
 				Obj()
 			gomega.Expect(k8sClient.Create(ctx, blockerJob)).Should(gomega.Succeed())
 
@@ -472,14 +471,14 @@ var _ = ginkgo.Describe("Metrics", func() {
 			higherJob1 = testingjob.MakeJob("high-large-1", ns.Name).
 				Queue(localQueue1.Name).
 				PriorityClass(highPriorityClass.Name).
-				Request(corev1.ResourceCPU, "4").
+				RequestAndLimit(corev1.ResourceCPU, "4").
 				Obj()
 			gomega.Expect(k8sClient.Create(ctx, higherJob1)).Should(gomega.Succeed())
 
 			higherJob2 = testingjob.MakeJob("high-large-2", ns.Name).
 				Queue(localQueue2.Name).
 				PriorityClass(highPriorityClass.Name).
-				Request(corev1.ResourceCPU, "4").
+				RequestAndLimit(corev1.ResourceCPU, "4").
 				Obj()
 			gomega.Expect(k8sClient.Create(ctx, higherJob2)).Should(gomega.Succeed())
 		})
diff --git a/test/e2e/singlecluster/pod_test.go b/test/e2e/singlecluster/pod_test.go
index 9a14bc6c6..547a93415 100644
--- a/test/e2e/singlecluster/pod_test.go
+++ b/test/e2e/singlecluster/pod_test.go
@@ -55,6 +55,7 @@ var _ = ginkgo.Describe("Pod groups", func() {
 	ginkgo.AfterEach(func() {
 		gomega.Expect(util.DeleteNamespace(ctx, k8sClient, ns)).To(gomega.Succeed())
 		util.ExpectObjectToBeDeleted(ctx, k8sClient, onDemandRF, true)
+		util.ExpectAllPodsInNamespaceDeleted(ctx, k8sClient, ns)
 	})
 
 	ginkgo.When("Single CQ", func() {
@@ -79,13 +80,14 @@ var _ = ginkgo.Describe("Pod groups", func() {
 		ginkgo.AfterEach(func() {
 			gomega.Expect(util.DeleteAllPodsInNamespace(ctx, k8sClient, ns)).To(gomega.Succeed())
 			util.ExpectObjectToBeDeleted(ctx, k8sClient, cq, true)
+			util.ExpectAllPodsInNamespaceDeleted(ctx, k8sClient, ns)
 		})
 
 		ginkgo.It("should admit group that fits", func() {
 			group := podtesting.MakePod("group", ns.Name).
 				Image(util.E2eTestAgnHostImage, util.BehaviorExitFast).
 				Queue(lq.Name).
-				Request(corev1.ResourceCPU, "1").
+				RequestAndLimit(corev1.ResourceCPU, "1").
 				MakeGroup(2)
 			gKey := client.ObjectKey{Namespace: ns.Name, Name: "group"}
 			for _, p := range group {
@@ -128,7 +130,7 @@ var _ = ginkgo.Describe("Pod groups", func() {
 			group := podtesting.MakePod("group", ns.Name).
 				Image(util.E2eTestAgnHostImage, util.BehaviorExitFast).
 				Queue(lq.Name).
-				Request(corev1.ResourceCPU, "1").
+				RequestAndLimit(corev1.ResourceCPU, "1").
 				MakeGroup(3)
 
 			ginkgo.By("Incomplete group should not start", func() {
@@ -180,7 +182,7 @@ var _ = ginkgo.Describe("Pod groups", func() {
 				Image(util.E2eTestAgnHostImage, util.BehaviorExitFast).
 				TerminationGracePeriod(1).
 				Queue(lq.Name).
-				Request(corev1.ResourceCPU, "1").
+				RequestAndLimit(corev1.ResourceCPU, "1").
 				MakeGroup(3)
 
 			// First pod runs for much longer, so that there is time to terminate it.
@@ -294,7 +296,7 @@ var _ = ginkgo.Describe("Pod groups", func() {
 			group := podtesting.MakePod("group", ns.Name).
 				Image(util.E2eTestAgnHostImage, util.BehaviorExitFast).
 				Queue(lq.Name).
-				Request(corev1.ResourceCPU, "1").
+				RequestAndLimit(corev1.ResourceCPU, "1").
 				MakeGroup(2)
 
 			// The first pod has a node selector for a missing node.
@@ -365,7 +367,7 @@ var _ = ginkgo.Describe("Pod groups", func() {
 			group := podtesting.MakePod("group", ns.Name).
 				Image(util.E2eTestAgnHostImage, util.BehaviorExitFast).
 				Queue(lq.Name).
-				Request(corev1.ResourceCPU, "3").
+				RequestAndLimit(corev1.ResourceCPU, "3").
 				MakeGroup(2)
 			gKey := client.ObjectKey{Namespace: ns.Name, Name: "group"}
 
@@ -423,7 +425,7 @@ var _ = ginkgo.Describe("Pod groups", func() {
 				Image(util.E2eTestAgnHostImage, util.BehaviorWaitForDeletionFailOnExit).
 				TerminationGracePeriod(1).
 				Queue(lq.Name).
-				Request(corev1.ResourceCPU, "2").
+				RequestAndLimit(corev1.ResourceCPU, "2").
 				MakeGroup(2)
 			defaultGroupKey := client.ObjectKey{Namespace: ns.Name, Name: "default-priority-group"}
 			defaultGroupPods := sets.New(
@@ -448,7 +450,7 @@ var _ = ginkgo.Describe("Pod groups", func() {
 				Image(util.E2eTestAgnHostImage, util.BehaviorWaitForDeletion).
 				Queue(lq.Name).
 				PriorityClass("high").
-				Request(corev1.ResourceCPU, "1").
+				RequestAndLimit(corev1.ResourceCPU, "1").
 				MakeGroup(2)
 			highGroupKey := client.ObjectKey{Namespace: ns.Name, Name: "high-priority-group"}
 
diff --git a/test/e2e/singlecluster/statefulset_test.go b/test/e2e/singlecluster/statefulset_test.go
index 71cd45989..164b7880d 100644
--- a/test/e2e/singlecluster/statefulset_test.go
+++ b/test/e2e/singlecluster/statefulset_test.go
@@ -82,13 +82,14 @@ var _ = ginkgo.Describe("StatefulSet integration", func() {
 		gomega.Expect(util.DeleteNamespace(ctx, k8sClient, ns)).To(gomega.Succeed())
 		util.ExpectObjectToBeDeleted(ctx, k8sClient, cq, true)
 		util.ExpectObjectToBeDeleted(ctx, k8sClient, rf, true)
+		util.ExpectAllPodsInNamespaceDeleted(ctx, k8sClient, ns)
 	})
 
 	ginkgo.When("StatefulSet created", func() {
 		ginkgo.It("should admit group that fits", func() {
 			statefulSet := statefulsettesting.MakeStatefulSet("sts", ns.Name).
 				Image(util.E2eTestAgnHostImage, util.BehaviorWaitForDeletion).
-				Request(corev1.ResourceCPU, "100m").
+				RequestAndLimit(corev1.ResourceCPU, "200m").
 				Replicas(3).
 				Queue(lq.Name).
 				Obj()
@@ -107,7 +108,7 @@ var _ = ginkgo.Describe("StatefulSet integration", func() {
 			ginkgo.By("Creating potentially conflicting stateful-set", func() {
 				conflictingStatefulSet := statefulsettesting.MakeStatefulSet("sts-conflict", ns.Name).
 					Image(util.E2eTestAgnHostImage, util.BehaviorWaitForDeletion).
-					Request(corev1.ResourceCPU, "100m").
+					RequestAndLimit(corev1.ResourceCPU, "200m").
 					Replicas(1).
 					Queue(lq.Name).
 					Obj()
@@ -144,7 +145,7 @@ var _ = ginkgo.Describe("StatefulSet integration", func() {
 		ginkgo.It("should allow to update the PodTemplate in StatefulSet", func() {
 			statefulSet := statefulsettesting.MakeStatefulSet("sts", ns.Name).
 				Image(util.E2eTestAgnHostImageOld, util.BehaviorWaitForDeletion).
-				Request(corev1.ResourceCPU, "100m").
+				RequestAndLimit(corev1.ResourceCPU, "200m").
 				Replicas(3).
 				Queue(lq.Name).
 				Obj()
@@ -194,7 +195,7 @@ var _ = ginkgo.Describe("StatefulSet integration", func() {
 		ginkgo.It("should delete all pods on scale down to zero", func() {
 			statefulSet := statefulsettesting.MakeStatefulSet("sts", ns.Name).
 				Image(util.E2eTestAgnHostImage, util.BehaviorWaitForDeletion).
-				Request(corev1.ResourceCPU, "100m").
+				RequestAndLimit(corev1.ResourceCPU, "200m").
 				Replicas(3).
 				Queue(lq.Name).
 				Obj()
@@ -242,7 +243,7 @@ var _ = ginkgo.Describe("StatefulSet integration", func() {
 		ginkgo.It("should create pods after scale up from zero", func() {
 			statefulSet := statefulsettesting.MakeStatefulSet("sts", ns.Name).
 				Image(util.E2eTestAgnHostImage, util.BehaviorWaitForDeletion).
-				Request(corev1.ResourceCPU, "100m").
+				RequestAndLimit(corev1.ResourceCPU, "200m").
 				Replicas(0).
 				Queue(lq.Name).
 				Obj()
@@ -278,7 +279,7 @@ var _ = ginkgo.Describe("StatefulSet integration", func() {
 		ginkgo.It("should allow to scale up after scale down to zero", func() {
 			statefulSet := statefulsettesting.MakeStatefulSet("sts", ns.Name).
 				Image(util.E2eTestAgnHostImage, util.BehaviorWaitForDeletion).
-				Request(corev1.ResourceCPU, "100m").
+				RequestAndLimit(corev1.ResourceCPU, "200m").
 				Replicas(3).
 				Queue(lq.Name).
 				Obj()
@@ -340,7 +341,7 @@ var _ = ginkgo.Describe("StatefulSet integration", func() {
 		ginkgo.It("should allow to change queue name if ReadyReplicas=0", func() {
 			statefulSet := statefulsettesting.MakeStatefulSet("sts", ns.Name).
 				Image(util.E2eTestAgnHostImage, util.BehaviorWaitForDeletion).
-				Request(corev1.ResourceCPU, "100m").
+				RequestAndLimit(corev1.ResourceCPU, "200m").
 				Replicas(3).
 				Queue(fmt.Sprintf("%s-invalid", localQueueName)).
 				Obj()
@@ -384,7 +385,7 @@ var _ = ginkgo.Describe("StatefulSet integration", func() {
 		ginkgo.It("should delete all Pods if StatefulSet was deleted after being partially ready", func() {
 			statefulSet := statefulsettesting.MakeStatefulSet("sts", ns.Name).
 				Image(util.E2eTestAgnHostImage, util.BehaviorWaitForDeletion).
-				Request(corev1.ResourceCPU, "100m").
+				RequestAndLimit(corev1.ResourceCPU, "200m").
 				Replicas(3).
 				Queue(localQueueName).
 				Obj()
diff --git a/test/e2e/singlecluster/suite_test.go b/test/e2e/singlecluster/suite_test.go
index d44f51975..fc08c99f3 100644
--- a/test/e2e/singlecluster/suite_test.go
+++ b/test/e2e/singlecluster/suite_test.go
@@ -28,7 +28,6 @@ import (
 	"github.com/onsi/gomega"
 	"k8s.io/client-go/rest"
 	"k8s.io/utils/clock"
-	ctrl "sigs.k8s.io/controller-runtime"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
 	visibilityv1beta1 "sigs.k8s.io/kueue/client-go/clientset/versioned/typed/visibility/v1beta1"
@@ -58,7 +57,7 @@ func TestAPIs(t *testing.T) {
 }
 
 var _ = ginkgo.BeforeSuite(func() {
-	ctrl.SetLogger(util.NewTestingLogger(ginkgo.GinkgoWriter, -3))
+	util.SetupLogger()
 
 	k8sClient, cfg = util.CreateClientUsingCluster("")
 	restClient = util.CreateRestClient(cfg)
diff --git a/test/e2e/singlecluster/tas_test.go b/test/e2e/singlecluster/tas_test.go
index 05664399f..c5700ab9a 100644
--- a/test/e2e/singlecluster/tas_test.go
+++ b/test/e2e/singlecluster/tas_test.go
@@ -54,6 +54,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling", func() {
 	})
 	ginkgo.AfterEach(func() {
 		gomega.Expect(util.DeleteNamespace(ctx, k8sClient, ns)).To(gomega.Succeed())
+		util.ExpectAllPodsInNamespaceDeleted(ctx, k8sClient, ns)
 	})
 
 	ginkgo.When("Creating a Job requesting TAS", func() {
@@ -97,8 +98,8 @@ var _ = ginkgo.Describe("TopologyAwareScheduling", func() {
 		ginkgo.It("should admit a Job via TAS", func() {
 			sampleJob := testingjob.MakeJob("test-job", ns.Name).
 				Queue(localQueue.Name).
-				Request("cpu", "700m").
-				Request("memory", "20Mi").
+				RequestAndLimit("cpu", "700m").
+				RequestAndLimit("memory", "20Mi").
 				Obj()
 			jobKey := client.ObjectKeyFromObject(sampleJob)
 			sampleJob = (&testingjob.JobWrapper{Job: *sampleJob}).
@@ -217,10 +218,10 @@ var _ = ginkgo.Describe("TopologyAwareScheduling", func() {
 						},
 					},
 				).
-				Request("rj1", "cpu", "200m").
-				Request("rj1", "memory", "20Mi").
-				Request("rj2", "cpu", "200m").
-				Request("rj2", "memory", "20Mi").
+				RequestAndLimit("rj1", "cpu", "200m").
+				RequestAndLimit("rj1", "memory", "20Mi").
+				RequestAndLimit("rj2", "cpu", "200m").
+				RequestAndLimit("rj2", "memory", "20Mi").
 				Obj()
 
 			ginkgo.By("Creating the JobSet", func() {
@@ -330,8 +331,8 @@ var _ = ginkgo.Describe("TopologyAwareScheduling", func() {
 				Queue(localQueue.Name).
 				Image(util.E2eTestAgnHostImage, util.BehaviorExitFast).
 				Annotation(kueuealpha.PodSetRequiredTopologyAnnotation, corev1.LabelHostname).
-				Request("cpu", "100m").
-				Request("memory", "100Mi").
+				RequestAndLimit("cpu", "200m").
+				RequestAndLimit("memory", "200Mi").
 				Obj()
 
 			ginkgo.By("Creating the Pod", func() {
@@ -389,8 +390,8 @@ var _ = ginkgo.Describe("TopologyAwareScheduling", func() {
 				Queue(localQueue.Name).
 				Image(util.E2eTestAgnHostImage, util.BehaviorExitFast).
 				Annotation(kueuealpha.PodSetRequiredTopologyAnnotation, corev1.LabelHostname).
-				Request("cpu", "100m").
-				Request("memory", "100Mi").
+				RequestAndLimit("cpu", "200m").
+				RequestAndLimit("memory", "200Mi").
 				MakeGroup(2)
 
 			ginkgo.By("Creating the Pod group", func() {
diff --git a/test/e2e/singlecluster/visibility_test.go b/test/e2e/singlecluster/visibility_test.go
index d3889bcb1..1198ba425 100644
--- a/test/e2e/singlecluster/visibility_test.go
+++ b/test/e2e/singlecluster/visibility_test.go
@@ -77,6 +77,8 @@ var _ = ginkgo.Describe("Kueue visibility server", func() {
 	ginkgo.AfterEach(func() {
 		gomega.Expect(util.DeleteNamespace(ctx, k8sClient, nsA)).To(gomega.Succeed())
 		gomega.Expect(util.DeleteNamespace(ctx, k8sClient, nsB)).To(gomega.Succeed())
+		util.ExpectAllPodsInNamespaceDeleted(ctx, k8sClient, nsA)
+		util.ExpectAllPodsInNamespaceDeleted(ctx, k8sClient, nsB)
 	})
 
 	ginkgo.When("There are pending workloads due to capacity maxed by the admitted job", func() {
@@ -112,7 +114,7 @@ var _ = ginkgo.Describe("Kueue visibility server", func() {
 				blockingJob = testingjob.MakeJob("test-job-1", nsA.Name).
 					Queue(localQueueA.Name).
 					Image(util.E2eTestAgnHostImage, util.BehaviorWaitForDeletion).
-					Request(corev1.ResourceCPU, "1").
+					RequestAndLimit(corev1.ResourceCPU, "1").
 					TerminationGracePeriod(1).
 					BackoffLimit(0).
 					PriorityClass(highPriorityClass.Name).
@@ -152,7 +154,7 @@ var _ = ginkgo.Describe("Kueue visibility server", func() {
 				sampleJob2 = testingjob.MakeJob("test-job-2", nsA.Name).
 					Queue(localQueueA.Name).
 					Image(util.E2eTestAgnHostImage, util.BehaviorExitFast).
-					Request(corev1.ResourceCPU, "1").
+					RequestAndLimit(corev1.ResourceCPU, "1").
 					PriorityClass(lowPriorityClass.Name).
 					Obj()
 				gomega.Expect(k8sClient.Create(ctx, sampleJob2)).Should(gomega.Succeed())
@@ -214,7 +216,7 @@ var _ = ginkgo.Describe("Kueue visibility server", func() {
 					job := testingjob.MakeJob(jobCase.JobName, nsA.Name).
 						Queue(jobCase.LocalQueueName).
 						Image(util.E2eTestAgnHostImage, util.BehaviorExitFast).
-						Request(corev1.ResourceCPU, "1").
+						RequestAndLimit(corev1.ResourceCPU, "1").
 						PriorityClass(jobCase.JobPrioClassName).
 						Obj()
 					gomega.Expect(k8sClient.Create(ctx, job)).Should(gomega.Succeed())
@@ -273,7 +275,7 @@ var _ = ginkgo.Describe("Kueue visibility server", func() {
 				sampleJob2 = testingjob.MakeJob("test-job-2", nsA.Name).
 					Queue(localQueueA.Name).
 					Image(util.E2eTestAgnHostImage, util.BehaviorExitFast).
-					Request(corev1.ResourceCPU, "1").
+					RequestAndLimit(corev1.ResourceCPU, "1").
 					PriorityClass(lowPriorityClass.Name).
 					Obj()
 				gomega.Expect(k8sClient.Create(ctx, sampleJob2)).Should(gomega.Succeed())
@@ -335,7 +337,7 @@ var _ = ginkgo.Describe("Kueue visibility server", func() {
 					job := testingjob.MakeJob(jobCase.JobName, nsA.Name).
 						Queue(jobCase.LocalQueueName).
 						Image(util.E2eTestAgnHostImage, util.BehaviorExitFast).
-						Request(corev1.ResourceCPU, "1").
+						RequestAndLimit(corev1.ResourceCPU, "1").
 						PriorityClass(jobCase.JobPrioClassName).
 						Obj()
 					gomega.Expect(k8sClient.Create(ctx, job)).Should(gomega.Succeed())
@@ -428,7 +430,7 @@ var _ = ginkgo.Describe("Kueue visibility server", func() {
 					job := testingjob.MakeJob(jobCase.JobName, jobCase.nsName).
 						Queue(jobCase.LocalQueueName).
 						Image(util.E2eTestAgnHostImage, util.BehaviorExitFast).
-						Request(corev1.ResourceCPU, "1").
+						RequestAndLimit(corev1.ResourceCPU, "1").
 						PriorityClass(jobCase.JobPrioClassName).
 						Obj()
 					gomega.Expect(k8sClient.Create(ctx, job)).Should(gomega.Succeed())
diff --git a/test/e2e/tas/appwrapper_test.go b/test/e2e/tas/appwrapper_test.go
index 15fe000d5..3e17648ca 100644
--- a/test/e2e/tas/appwrapper_test.go
+++ b/test/e2e/tas/appwrapper_test.go
@@ -92,12 +92,10 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for AppWrapper", func() {
 				Component(utiltestingjob.MakeJob("job-0", ns.Name).
 					Parallelism(int32(numPods)).
 					Completions(int32(numPods)).
-					Request(corev1.ResourceCPU, "100m").
-					Limit(corev1.ResourceCPU, "100m").
-					Request(extraResource, "1").
-					Limit(extraResource, "1").
+					RequestAndLimit(corev1.ResourceCPU, "200m").
+					RequestAndLimit(extraResource, "1").
 					Suspend(false).
-					Image(util.E2eTestAgnHostImage, util.BehaviorWaitForDeletion).
+					Image(util.E2eTestAgnHostImage, util.BehaviorExitFast).
 					PodAnnotation(kueuealpha.PodSetPreferredTopologyAnnotation, testing.DefaultRackTopologyLevel).
 					SetTypeMeta().Obj()).
 				Queue(localQueue.Name).
@@ -138,10 +136,9 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for AppWrapper", func() {
 				Completions(int32(numPods)).
 				Indexed(true).
 				Suspend(false).
-				Request(extraResource, "1").
-				Limit(extraResource, "1").
+				RequestAndLimit(extraResource, "1").
 				PodAnnotation(kueuealpha.PodSetRequiredTopologyAnnotation, testing.DefaultBlockTopologyLevel).
-				Image(util.E2eTestAgnHostImage, util.BehaviorWaitForDeletion).
+				Image(util.E2eTestAgnHostImage, util.BehaviorExitFast).
 				SetTypeMeta().
 				Obj()
 			aw := awtesting.MakeAppWrapper("aw-ranks-job", ns.Name).
diff --git a/test/e2e/tas/job_test.go b/test/e2e/tas/job_test.go
index ffa638c31..47447f577 100644
--- a/test/e2e/tas/job_test.go
+++ b/test/e2e/tas/job_test.go
@@ -56,6 +56,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for Job", func() {
 	})
 	ginkgo.AfterEach(func() {
 		gomega.Expect(util.DeleteNamespace(ctx, k8sClient, ns)).To(gomega.Succeed())
+		util.ExpectAllPodsInNamespaceDeleted(ctx, k8sClient, ns)
 	})
 
 	ginkgo.When("Creating a Job", func() {
@@ -101,8 +102,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for Job", func() {
 				Queue(localQueue.Name).
 				Parallelism(3).
 				Completions(3).
-				Request(extraResource, "1").
-				Limit(extraResource, "1").
+				RequestAndLimit(extraResource, "1").
 				Obj()
 			sampleJob = (&testingjob.JobWrapper{Job: *sampleJob}).
 				PodAnnotation(kueuealpha.PodSetRequiredTopologyAnnotation, testing.DefaultRackTopologyLevel).
@@ -125,8 +125,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for Job", func() {
 				Queue(localQueue.Name).
 				Parallelism(3).
 				Completions(3).
-				Request(extraResource, "1").
-				Limit(extraResource, "1").
+				RequestAndLimit(extraResource, "1").
 				Obj()
 			sampleJob = (&testingjob.JobWrapper{Job: *sampleJob}).
 				PodAnnotation(kueuealpha.PodSetPreferredTopologyAnnotation, testing.DefaultRackTopologyLevel).
@@ -178,8 +177,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for Job", func() {
 				Queue(localQueue.Name).
 				Parallelism(3).
 				Completions(3).
-				Request(extraResource, "1").
-				Limit(extraResource, "1").
+				RequestAndLimit(extraResource, "1").
 				Obj()
 			sampleJob = (&testingjob.JobWrapper{Job: *sampleJob}).
 				PodAnnotation(kueuealpha.PodSetRequiredTopologyAnnotation, testing.DefaultBlockTopologyLevel).
@@ -232,8 +230,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for Job", func() {
 				Queue(localQueue.Name).
 				Parallelism(2).
 				Completions(3).
-				Request(extraResource, "1").
-				Limit(extraResource, "1").
+				RequestAndLimit(extraResource, "1").
 				Obj()
 			sampleJob = (&testingjob.JobWrapper{Job: *sampleJob}).
 				PodAnnotation(kueuealpha.PodSetRequiredTopologyAnnotation, testing.DefaultBlockTopologyLevel).
@@ -261,8 +258,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for Job", func() {
 				Parallelism(int32(numPods)).
 				Completions(int32(numPods)).
 				Indexed(true).
-				Request(extraResource, "1").
-				Limit(extraResource, "1").
+				RequestAndLimit(extraResource, "1").
 				Obj()
 			sampleJob = (&testingjob.JobWrapper{Job: *sampleJob}).
 				PodAnnotation(kueuealpha.PodSetRequiredTopologyAnnotation, testing.DefaultBlockTopologyLevel).
diff --git a/test/e2e/tas/jobset_test.go b/test/e2e/tas/jobset_test.go
index e0b7dad12..7e8ace75e 100644
--- a/test/e2e/tas/jobset_test.go
+++ b/test/e2e/tas/jobset_test.go
@@ -48,6 +48,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for JobSet", func() {
 	})
 	ginkgo.AfterEach(func() {
 		gomega.Expect(util.DeleteNamespace(ctx, k8sClient, ns)).To(gomega.Succeed())
+		util.ExpectAllPodsInNamespaceDeleted(ctx, k8sClient, ns)
 	})
 
 	ginkgo.When("Creating a JobSet", func() {
@@ -98,7 +99,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for JobSet", func() {
 					testingjobset.ReplicatedJobRequirements{
 						Name:        "replicated-job-1",
 						Image:       util.E2eTestAgnHostImage,
-						Args:        util.BehaviorWaitForDeletion,
+						Args:        util.BehaviorExitFast,
 						Replicas:    int32(replicas),
 						Parallelism: int32(parallelism),
 						Completions: int32(parallelism),
@@ -107,8 +108,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for JobSet", func() {
 						},
 					},
 				).
-				Request("replicated-job-1", extraResource, "1").
-				Limit("replicated-job-1", extraResource, "1").
+				RequestAndLimit("replicated-job-1", extraResource, "1").
 				Obj()
 			gomega.Expect(k8sClient.Create(ctx, sampleJob)).Should(gomega.Succeed())
 
diff --git a/test/e2e/tas/mpijob_test.go b/test/e2e/tas/mpijob_test.go
index f9618fa4a..cda56937e 100644
--- a/test/e2e/tas/mpijob_test.go
+++ b/test/e2e/tas/mpijob_test.go
@@ -115,12 +115,10 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for MPIJob", func() {
 						},
 					},
 				).
-				Image(kfmpi.MPIReplicaTypeLauncher, util.E2eTestAgnHostImage, util.BehaviorWaitForDeletion).
-				Image(kfmpi.MPIReplicaTypeWorker, util.E2eTestAgnHostImage, util.BehaviorWaitForDeletion).
-				Request(kfmpi.MPIReplicaTypeLauncher, corev1.ResourceCPU, "100m").
-				Limit(kfmpi.MPIReplicaTypeLauncher, corev1.ResourceCPU, "100m").
-				Request(kfmpi.MPIReplicaTypeWorker, extraResource, "1").
-				Limit(kfmpi.MPIReplicaTypeWorker, extraResource, "1").
+				Image(kfmpi.MPIReplicaTypeLauncher, util.E2eTestAgnHostImage, util.BehaviorExitFast).
+				Image(kfmpi.MPIReplicaTypeWorker, util.E2eTestAgnHostImage, util.BehaviorExitFast).
+				RequestAndLimit(kfmpi.MPIReplicaTypeLauncher, corev1.ResourceCPU, "200m").
+				RequestAndLimit(kfmpi.MPIReplicaTypeWorker, extraResource, "1").
 				Obj()
 			gomega.Expect(k8sClient.Create(ctx, mpijob)).Should(gomega.Succeed())
 
diff --git a/test/e2e/tas/pod_group_test.go b/test/e2e/tas/pod_group_test.go
index fa28269b4..3c5324233 100644
--- a/test/e2e/tas/pod_group_test.go
+++ b/test/e2e/tas/pod_group_test.go
@@ -43,6 +43,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for Pod group", func() {
 	})
 	ginkgo.AfterEach(func() {
 		gomega.Expect(util.DeleteNamespace(ctx, k8sClient, ns)).To(gomega.Succeed())
+		util.ExpectAllPodsInNamespaceDeleted(ctx, k8sClient, ns)
 	})
 
 	ginkgo.When("Creating a Pod group", func() {
@@ -88,8 +89,9 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for Pod group", func() {
 			numPods := 4
 			basePod := testingpod.MakePod("test-pod", ns.Name).
 				Queue("test-queue").
-				Request(extraResource, "1").
+				RequestAndLimit(extraResource, "1").
 				Limit(extraResource, "1").
+				Image(util.E2eTestAgnHostImage, util.BehaviorExitFast).
 				Annotation(kueuealpha.PodSetRequiredTopologyAnnotation, testing.DefaultBlockTopologyLevel)
 			podGroup := basePod.MakeIndexedGroup(numPods)
 
diff --git a/test/e2e/tas/pytorch_test.go b/test/e2e/tas/pytorch_test.go
index af86490b3..c0e0da35e 100644
--- a/test/e2e/tas/pytorch_test.go
+++ b/test/e2e/tas/pytorch_test.go
@@ -114,12 +114,10 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for PyTorchJob", func() {
 						},
 					},
 				).
-				Image(kftraining.PyTorchJobReplicaTypeMaster, util.E2eTestAgnHostImage, util.BehaviorWaitForDeletion).
-				Image(kftraining.PyTorchJobReplicaTypeWorker, util.E2eTestAgnHostImage, util.BehaviorWaitForDeletion).
-				Request(kftraining.PyTorchJobReplicaTypeMaster, corev1.ResourceCPU, "100m").
-				Limit(kftraining.PyTorchJobReplicaTypeMaster, corev1.ResourceCPU, "100m").
-				Request(kftraining.PyTorchJobReplicaTypeWorker, extraResource, "1").
-				Limit(kftraining.PyTorchJobReplicaTypeWorker, extraResource, "1").
+				Image(kftraining.PyTorchJobReplicaTypeMaster, util.E2eTestAgnHostImage, util.BehaviorExitFast).
+				Image(kftraining.PyTorchJobReplicaTypeWorker, util.E2eTestAgnHostImage, util.BehaviorExitFast).
+				RequestAndLimit(kftraining.PyTorchJobReplicaTypeMaster, corev1.ResourceCPU, "200m").
+				RequestAndLimit(kftraining.PyTorchJobReplicaTypeWorker, extraResource, "1").
 				Obj()
 			gomega.Expect(k8sClient.Create(ctx, pytorchjob)).Should(gomega.Succeed())
 
diff --git a/test/e2e/tas/rayjob_test.go b/test/e2e/tas/rayjob_test.go
index 20f8aad69..e4896ff26 100644
--- a/test/e2e/tas/rayjob_test.go
+++ b/test/e2e/tas/rayjob_test.go
@@ -110,10 +110,10 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for RayJob", ginkgo.Ordered, fu
 										Name: "head-container",
 										Resources: corev1.ResourceRequirements{
 											Requests: corev1.ResourceList{
-												corev1.ResourceCPU: resource.MustParse("100m"),
+												corev1.ResourceCPU: resource.MustParse("200m"),
 											},
 											Limits: corev1.ResourceList{
-												corev1.ResourceCPU: resource.MustParse("100m"),
+												corev1.ResourceCPU: resource.MustParse("200m"),
 											},
 										},
 									},
diff --git a/test/e2e/tas/statefulset_test.go b/test/e2e/tas/statefulset_test.go
index e63ecc1f0..c248e3435 100644
--- a/test/e2e/tas/statefulset_test.go
+++ b/test/e2e/tas/statefulset_test.go
@@ -80,8 +80,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for StatefulSet", func() {
 			const replicas = 3
 			sts := statefulset.MakeStatefulSet("sts", ns.Name).
 				Image(util.E2eTestAgnHostImage, util.BehaviorWaitForDeletion).
-				Request(extraResource, "1").
-				Limit(extraResource, "1").
+				RequestAndLimit(extraResource, "1").
 				Replicas(replicas).
 				Queue(localQueue.Name).
 				PodTemplateSpecAnnotation(kueuealpha.PodSetRequiredTopologyAnnotation, testing.DefaultBlockTopologyLevel).
diff --git a/test/e2e/tas/suite_test.go b/test/e2e/tas/suite_test.go
index 5a3498a42..717b18c45 100644
--- a/test/e2e/tas/suite_test.go
+++ b/test/e2e/tas/suite_test.go
@@ -27,7 +27,6 @@ import (
 	"github.com/onsi/gomega"
 	corev1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/api/resource"
-	ctrl "sigs.k8s.io/controller-runtime"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
 	clientutil "sigs.k8s.io/kueue/pkg/util/client"
@@ -51,7 +50,7 @@ func TestAPIs(t *testing.T) {
 }
 
 var _ = ginkgo.BeforeSuite(func() {
-	ctrl.SetLogger(util.NewTestingLogger(ginkgo.GinkgoWriter, -3))
+	util.SetupLogger()
 
 	k8sClient, _ = util.CreateClientUsingCluster("")
 	ctx = context.Background()
diff --git a/test/integration/framework/framework.go b/test/integration/framework/framework.go
index 2a559b511..3c7ac6c50 100644
--- a/test/integration/framework/framework.go
+++ b/test/integration/framework/framework.go
@@ -25,7 +25,6 @@ import (
 	"path/filepath"
 	"strconv"
 	"strings"
-	"sync"
 	"time"
 
 	kfmpi "github.com/kubeflow/mpi-operator/pkg/apis/kubeflow/v2beta1"
@@ -68,12 +67,8 @@ type Framework struct {
 	managerDone   <-chan struct{}
 }
 
-var setupLogger = sync.OnceFunc(func() {
-	ctrl.SetLogger(util.NewTestingLogger(ginkgo.GinkgoWriter, -3))
-})
-
 func (f *Framework) Init() *rest.Config {
-	setupLogger()
+	util.SetupLogger()
 
 	var cfg *rest.Config
 	ginkgo.By("bootstrapping test environment", func() {
diff --git a/test/integration/singlecluster/controller/jobs/job/job_controller_test.go b/test/integration/singlecluster/controller/jobs/job/job_controller_test.go
index a21cdac26..1dfc85f2a 100644
--- a/test/integration/singlecluster/controller/jobs/job/job_controller_test.go
+++ b/test/integration/singlecluster/controller/jobs/job/job_controller_test.go
@@ -2655,4 +2655,56 @@ var _ = ginkgo.Describe("Job controller when TopologyAwareScheduling enabled", g
 			}, util.Timeout, util.Interval).Should(gomega.Succeed())
 		})
 	})
+
+	ginkgo.It("should admit workload with topology unconstrained annotation which fits", func() {
+		job := testingjob.MakeJob("job", ns.Name).
+			Queue(localQueue.Name).
+			PodAnnotation(kueuealpha.PodSetUnconstrainedTopologyAnnotation, "true").
+			Request(corev1.ResourceCPU, "1").
+			Obj()
+		ginkgo.By("creating a job", func() {
+			gomega.Expect(k8sClient.Create(ctx, job)).Should(gomega.Succeed())
+		})
+
+		wl := &kueue.Workload{}
+		wlLookupKey := types.NamespacedName{Name: workloadjob.GetWorkloadNameForJob(job.Name, job.UID), Namespace: ns.Name}
+
+		ginkgo.By("verify the workload is created", func() {
+			gomega.Eventually(func(g gomega.Gomega) {
+				g.Expect(k8sClient.Get(ctx, wlLookupKey, wl)).Should(gomega.Succeed())
+				g.Expect(wl.Spec.PodSets).Should(gomega.BeComparableTo([]kueue.PodSet{{
+					Name:  kueue.DefaultPodSetName,
+					Count: 1,
+					TopologyRequest: &kueue.PodSetTopologyRequest{
+						Unconstrained: ptr.To(true),
+						PodIndexLabel: ptr.To(batchv1.JobCompletionIndexAnnotation),
+					},
+				}}, cmpopts.IgnoreFields(kueue.PodSet{}, "Template")))
+			}, util.Timeout, util.Interval).Should(gomega.Succeed())
+		})
+
+		ginkgo.By("verify the workload is admitted", func() {
+			gomega.Eventually(func(g gomega.Gomega) {
+				g.Expect(k8sClient.Get(ctx, wlLookupKey, wl)).Should(gomega.Succeed())
+			}, util.Timeout, util.Interval).Should(gomega.Succeed())
+
+			util.ExpectWorkloadsToBeAdmitted(ctx, k8sClient, wl)
+			util.ExpectReservingActiveWorkloadsMetric(clusterQueue, 1)
+		})
+
+		ginkgo.By("verify admission for the workload", func() {
+			wlLookupKey := types.NamespacedName{Name: workloadjob.GetWorkloadNameForJob(job.Name, job.UID), Namespace: ns.Name}
+			gomega.Eventually(func(g gomega.Gomega) {
+				g.Expect(k8sClient.Get(ctx, wlLookupKey, wl)).Should(gomega.Succeed())
+				g.Expect(wl.Status.Admission).ShouldNot(gomega.BeNil())
+				g.Expect(wl.Status.Admission.PodSetAssignments).Should(gomega.HaveLen(1))
+				g.Expect(wl.Status.Admission.PodSetAssignments[0].TopologyAssignment).Should(gomega.BeComparableTo(
+					&kueue.TopologyAssignment{
+						Levels:  []string{tasBlockLabel},
+						Domains: []kueue.TopologyDomainAssignment{{Count: 1, Values: []string{"b1"}}},
+					},
+				))
+			}, util.Timeout, util.Interval).Should(gomega.Succeed())
+		})
+	})
 })
diff --git a/test/integration/singlecluster/scheduler/fairsharing/fair_sharing_test.go b/test/integration/singlecluster/scheduler/fairsharing/fair_sharing_test.go
index 9a67f5654..18acc0a57 100644
--- a/test/integration/singlecluster/scheduler/fairsharing/fair_sharing_test.go
+++ b/test/integration/singlecluster/scheduler/fairsharing/fair_sharing_test.go
@@ -281,7 +281,7 @@ var _ = ginkgo.Describe("Scheduler", func() {
 			ginkgo.By("Finishing eviction of 1 running workloads in the CQ with highest usage: cqA")
 			finishEvictionOfWorkloadsInCQ(cqA, 1)
 			util.ExpectReservingActiveWorkloadsMetric(cqC, 1)
-			util.ExpectClusterQueueWeightedShareMetric(cqA, 222)
+			util.ExpectClusterQueueWeightedShareMetric(cqA, 111)
 			util.ExpectClusterQueueWeightedShareMetric(cqB, 111)
 			util.ExpectClusterQueueWeightedShareMetric(cqC, 0)
 
@@ -291,7 +291,7 @@ var _ = ginkgo.Describe("Scheduler", func() {
 			gomega.Eventually(func(g gomega.Gomega) {
 				g.Expect(k8sClient.Get(ctx, cqAKey, createdCqA)).Should(gomega.Succeed())
 				g.Expect(createdCqA.Status.FairSharing).ShouldNot(gomega.BeNil())
-				g.Expect(createdCqA.Status.FairSharing).Should(gomega.BeComparableTo(&kueue.FairSharingStatus{WeightedShare: 222}))
+				g.Expect(createdCqA.Status.FairSharing).Should(gomega.BeComparableTo(&kueue.FairSharingStatus{WeightedShare: 111}))
 			}, util.Timeout, util.Interval).Should(gomega.Succeed())
 		})
 	})
diff --git a/test/util/e2e.go b/test/util/e2e.go
index f75063d35..5b57aa41b 100644
--- a/test/util/e2e.go
+++ b/test/util/e2e.go
@@ -26,6 +26,7 @@ import (
 	"github.com/google/go-cmp/cmp/cmpopts"
 	kfmpi "github.com/kubeflow/mpi-operator/pkg/apis/kubeflow/v2beta1"
 	kftraining "github.com/kubeflow/training-operator/pkg/apis/kubeflow.org/v1"
+	"github.com/onsi/ginkgo/v2"
 	"github.com/onsi/gomega"
 	awv1beta2 "github.com/project-codeflare/appwrapper/api/v1beta2"
 	rayv1 "github.com/ray-project/kuberay/ray-operator/apis/ray/v1"
@@ -164,6 +165,8 @@ func rolloutOperatorDeployment(ctx context.Context, k8sClient client.Client, key
 func waitForOperatorAvailability(ctx context.Context, k8sClient client.Client, key types.NamespacedName) {
 	deployment := &appsv1.Deployment{}
 	pods := &corev1.PodList{}
+	waitForAvailableStart := time.Now()
+	ginkgo.By(fmt.Sprintf("Waiting for availability of deployment: %q", key))
 	gomega.EventuallyWithOffset(2, func(g gomega.Gomega) error {
 		g.Expect(k8sClient.Get(ctx, key, deployment)).To(gomega.Succeed())
 		g.Expect(k8sClient.List(ctx, pods, client.InNamespace(key.Namespace), client.MatchingLabels(deployment.Spec.Selector.MatchLabels))).To(gomega.Succeed())
@@ -184,6 +187,7 @@ func waitForOperatorAvailability(ctx context.Context, k8sClient client.Client, k
 		))
 		return nil
 	}, StartUpTimeout, Interval).Should(gomega.Succeed())
+	ginkgo.GinkgoLogr.Info("Deployment is available in the cluster", "deployment", key, "waitingTime", time.Since(waitForAvailableStart))
 }
 
 func WaitForKueueAvailability(ctx context.Context, k8sClient client.Client) {
diff --git a/test/util/util.go b/test/util/util.go
index 8054d8e22..ad1042948 100644
--- a/test/util/util.go
+++ b/test/util/util.go
@@ -25,6 +25,8 @@ import (
 	"os"
 	"path/filepath"
 	"slices"
+	"strconv"
+	"sync"
 	"time"
 
 	"github.com/go-logr/logr"
@@ -55,6 +57,7 @@ import (
 	"k8s.io/klog/v2"
 	"k8s.io/utils/clock"
 	"k8s.io/utils/ptr"
+	ctrl "sigs.k8s.io/controller-runtime"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
 	"sigs.k8s.io/controller-runtime/pkg/log/zap"
@@ -70,6 +73,22 @@ import (
 	"sigs.k8s.io/kueue/pkg/workload"
 )
 
+const (
+	defaultLogLevel = -3
+)
+
+func logLevel() int {
+	level, err := strconv.Atoi(os.Getenv("TEST_LOG_LEVEL"))
+	if err != nil {
+		return defaultLogLevel
+	}
+	return level
+}
+
+var SetupLogger = sync.OnceFunc(func() {
+	ctrl.SetLogger(NewTestingLogger(ginkgo.GinkgoWriter, logLevel()))
+})
+
 type objAsPtr[T any] interface {
 	client.Object
 	*T
@@ -198,8 +217,8 @@ func deleteAllPodsInNamespace(ctx context.Context, c client.Client, ns *corev1.N
 func ExpectAllPodsInNamespaceDeleted(ctx context.Context, c client.Client, ns *corev1.Namespace) {
 	pods := corev1.PodList{}
 	gomega.Eventually(func(g gomega.Gomega) {
-		g.Expect(c.List(ctx, &pods, client.InNamespace(ns.Name))).Should(gomega.Succeed())
-		g.Expect(pods.Items).Should(gomega.BeEmpty())
+		g.ExpectWithOffset(1, c.List(ctx, &pods, client.InNamespace(ns.Name))).Should(gomega.Succeed())
+		g.ExpectWithOffset(1, pods.Items).Should(gomega.BeEmpty())
 	}, LongTimeout, Interval).Should(gomega.Succeed())
 }