-
Notifications
You must be signed in to change notification settings - Fork 501
add priority class to wl none -> some #8480
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 11 commits
52a3e03
960d7d3
a2a18f9
4c6a28a
dd27de7
076aa7a
ca335de
79d6a4b
116e539
03674a6
1e72145
efdabfb
023b1e7
ea8d6c7
399845c
6abdbb3
57b8205
1e78b9e
9896790
fe2ba6f
d0098d8
c29aa7d
543282c
e49c14d
d7d305b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2734,3 +2734,77 @@ func TestReconcile(t *testing.T) { | |
| } | ||
| } | ||
| } | ||
|
|
||
| // TestWorkloadPriorityClassChanged tests the workloadPriorityClassChanged function. | ||
| // (none -> some) should be detected as a change and trigger reconciliation. | ||
andrewseif marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| func TestWorkloadPriorityClassChanged(t *testing.T) { | ||
| testCases := map[string]struct { | ||
| oldWorkload *kueue.Workload | ||
| newWorkload *kueue.Workload | ||
| wantChanged bool | ||
| }{ | ||
| "no priority class on either workload": { | ||
| oldWorkload: utiltestingapi.MakeWorkload("wl", "ns").Obj(), | ||
| newWorkload: utiltestingapi.MakeWorkload("wl", "ns").Obj(), | ||
| wantChanged: false, | ||
| }, | ||
| "same priority class on both workloads": { | ||
| oldWorkload: utiltestingapi.MakeWorkload("wl", "ns"). | ||
| WorkloadPriorityClassRef("priority-1"). | ||
| Obj(), | ||
| newWorkload: utiltestingapi.MakeWorkload("wl", "ns"). | ||
| WorkloadPriorityClassRef("priority-1"). | ||
| Obj(), | ||
| wantChanged: false, | ||
| }, | ||
| "priority class changed from one to another": { | ||
| oldWorkload: utiltestingapi.MakeWorkload("wl", "ns"). | ||
| WorkloadPriorityClassRef("priority-1"). | ||
| Obj(), | ||
| newWorkload: utiltestingapi.MakeWorkload("wl", "ns"). | ||
| WorkloadPriorityClassRef("priority-2"). | ||
| Obj(), | ||
| wantChanged: true, | ||
| }, | ||
| "priority class added (none -> some)": { | ||
| oldWorkload: utiltestingapi.MakeWorkload("wl", "ns").Obj(), | ||
| newWorkload: utiltestingapi.MakeWorkload("wl", "ns"). | ||
| WorkloadPriorityClassRef("priority-1"). | ||
| Obj(), | ||
| wantChanged: true, | ||
| }, | ||
| "priority class removed (some -> none) - blocked by validation": { | ||
| oldWorkload: utiltestingapi.MakeWorkload("wl", "ns"). | ||
| WorkloadPriorityClassRef("priority-1"). | ||
| Obj(), | ||
| newWorkload: utiltestingapi.MakeWorkload("wl", "ns").Obj(), | ||
| // Removal is blocked by validation, so we don't need to detect it | ||
| wantChanged: false, | ||
| }, | ||
| "PodPriorityClass (not WorkloadPriorityClass) changed - should not trigger": { | ||
| oldWorkload: utiltestingapi.MakeWorkload("wl", "ns"). | ||
| PodPriorityClassRef("pod-priority-1"). | ||
| Obj(), | ||
| newWorkload: utiltestingapi.MakeWorkload("wl", "ns"). | ||
| PodPriorityClassRef("pod-priority-2"). | ||
| Obj(), | ||
| wantChanged: false, | ||
| }, | ||
| "PodPriorityClass added (none -> some) - should not trigger": { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would also be great to add a test case where we change the priority value. It should work only for WorkloadPriorityClass.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this got me thinking, is there a case where Kind changed from PodPriority to WorkloadPriority but uses same name? do we need to cover that?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, it would be great to cover this case as well. |
||
| oldWorkload: utiltestingapi.MakeWorkload("wl", "ns").Obj(), | ||
| newWorkload: utiltestingapi.MakeWorkload("wl", "ns"). | ||
| PodPriorityClassRef("pod-priority-1"). | ||
| Obj(), | ||
| wantChanged: false, | ||
| }, | ||
| } | ||
|
|
||
| for name, tc := range testCases { | ||
| t.Run(name, func(t *testing.T) { | ||
| gotChanged := workloadPriorityChanged(tc.oldWorkload, tc.newWorkload) | ||
| if gotChanged != tc.wantChanged { | ||
| t.Errorf("workloadPriorityClassChanged() = %v, want %v", gotChanged, tc.wantChanged) | ||
andrewseif marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
| }) | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -154,11 +154,13 @@ func validatedUpdateForEnabledWorkloadSlice(oldJob, newJob GenericJob) field.Err | |
| } | ||
|
|
||
| func ValidateUpdateForWorkloadPriorityClassName(isSuspended bool, oldObj, newObj client.Object) field.ErrorList { | ||
| // Cannot ADD a priority class to a NON-suspended (running) workload && wpc is empty | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we want to support adding a priority class, I think we should allow it.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. as far as I understand the issue mentioned suspended workloads, this piece of code is only affecting running on. If we change this if condition, it means we allow priority change to running workloads (if I get the code right?)
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, I see, you right, we want to fix only suspended workloads. |
||
| if !isSuspended && IsWorkloadPriorityClassNameEmpty(oldObj) { | ||
| if !IsWorkloadPriorityClassNameEmpty(newObj) { | ||
| return field.ErrorList{field.Invalid(workloadPriorityClassNamePath, WorkloadPriorityClassName(newObj), "WorkloadPriorityClass cannot be added to a non-suspended workload")} | ||
| } | ||
| } | ||
| // Cannot REMOVE a priority class from a workload (regardless of suspended/running) | ||
| if IsWorkloadPriorityClassNameEmpty(newObj) { | ||
| if !IsWorkloadPriorityClassNameEmpty(oldObj) { | ||
| return field.ErrorList{field.Invalid(workloadPriorityClassNamePath, WorkloadPriorityClassName(newObj), "WorkloadPriorityClass cannot be removed from a workload")} | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -259,6 +259,82 @@ var _ = ginkgo.Describe("Preemption", func() { | |
| cQPath := "/" + cq.Name | ||
| util.ExpectPreemptedCondition(ctx, k8sClient, kueue.InClusterQueueReason, metav1.ConditionTrue, lowWl, highWl, string(highWl.UID), "job-uid", cQPath, cQPath) | ||
| }) | ||
|
|
||
| ginkgo.It("Should trigger preemption when WorkloadPriorityClass is added to suspended workload", func() { | ||
| ginkgo.By("Creating a normal priority workload that gets admitted and uses all quota") | ||
|
|
||
| normalPrioClass := utiltestingapi.MakeWorkloadPriorityClass("normal-priority"). | ||
| PriorityValue(0). | ||
| Obj() | ||
| util.MustCreate(ctx, k8sClient, normalPrioClass) | ||
| defer func() { | ||
| util.ExpectObjectToBeDeleted(ctx, k8sClient, normalPrioClass, true) | ||
| }() | ||
|
|
||
| normalWl := utiltestingapi.MakeWorkload("normal-wl", ns.Name). | ||
| Queue(kueue.LocalQueueName(q.Name)). | ||
| Priority(0). | ||
| Request(corev1.ResourceCPU, "4"). | ||
| Obj() | ||
|
|
||
| normalWl.Spec.PriorityClassRef = &kueue.PriorityClassRef{ | ||
| Group: kueue.WorkloadPriorityClassGroup, | ||
| Kind: "WorkloadPriorityClass", | ||
| Name: "normal-priority", | ||
| } | ||
|
|
||
| util.MustCreate(ctx, k8sClient, normalWl) | ||
| util.ExpectWorkloadsToHaveQuotaReservation(ctx, k8sClient, cq.Name, normalWl) | ||
|
|
||
| ginkgo.By("Creating a suspended workload WITHOUT priority class") | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you mean deactivated workload, right?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we add test case here instead? And also apply case from issue.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
if I am guessing correctly, in this context you mean: if so then its deactivated.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yes, but this case applies only to jobs. Only jobs can be suspended. Deactivation is not the same as suspension.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we might have a bug here I am not sure how exactly everything ties together yet, but it seems this function uses the problematic I think we might need to change it, but I think someone with more experience and knowledge should also validate my understanding.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure I got what's wrong with
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you please explain in which case you have a bug? |
||
| suspendedWl := utiltestingapi.MakeWorkload("suspended-wl", ns.Name). | ||
| Queue(kueue.LocalQueueName(q.Name)). | ||
| Request(corev1.ResourceCPU, "4"). | ||
| Active(false). | ||
| Obj() | ||
| util.MustCreate(ctx, k8sClient, suspendedWl) | ||
|
|
||
| ginkgo.By("Adding high WorkloadPriorityClass to the suspended workload") | ||
| gomega.Eventually(func(g gomega.Gomega) { | ||
| wl := &kueue.Workload{} | ||
| g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(suspendedWl), wl)).To(gomega.Succeed()) | ||
| wl.Spec.PriorityClassRef = &kueue.PriorityClassRef{ | ||
| Group: kueue.WorkloadPriorityClassGroup, | ||
| Kind: "WorkloadPriorityClass", | ||
| Name: "high-priority", | ||
| } | ||
| wl.Spec.Priority = ptr.To(highPriority) | ||
| g.Expect(k8sClient.Update(ctx, wl)).To(gomega.Succeed()) | ||
| }, util.Timeout, util.Interval).Should(gomega.Succeed()) | ||
|
|
||
| ginkgo.By("Verifying the priority class was added") | ||
| gomega.Eventually(func(g gomega.Gomega) { | ||
| wl := &kueue.Workload{} | ||
| g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(suspendedWl), wl)).To(gomega.Succeed()) | ||
| g.Expect(wl.Spec.PriorityClassRef).NotTo(gomega.BeNil()) | ||
| g.Expect(wl.Spec.PriorityClassRef.Name).To(gomega.Equal("high-priority")) | ||
| g.Expect(wl.Spec.Priority).NotTo(gomega.BeNil()) | ||
| g.Expect(*wl.Spec.Priority).To(gomega.Equal(highPriority)) | ||
| }, util.Timeout, util.Interval).Should(gomega.Succeed()) | ||
|
|
||
| ginkgo.By("Unsuspending the workload (set Active=true)") | ||
| gomega.Eventually(func(g gomega.Gomega) { | ||
| wl := &kueue.Workload{} | ||
| g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(suspendedWl), wl)).To(gomega.Succeed()) | ||
| wl.Spec.Active = ptr.To(true) | ||
| g.Expect(k8sClient.Update(ctx, wl)).To(gomega.Succeed()) | ||
| }, util.Timeout, util.Interval).Should(gomega.Succeed()) | ||
|
|
||
| ginkgo.By("Verifying the normal priority workload gets preempted") | ||
| util.ExpectWorkloadsToBePreempted(ctx, k8sClient, normalWl) | ||
| util.FinishEvictionForWorkloads(ctx, k8sClient, normalWl) | ||
|
|
||
| ginkgo.By("Verifying the high-priority workload gets admitted") | ||
| util.ExpectWorkloadsToHaveQuotaReservation(ctx, k8sClient, cq.Name, suspendedWl) | ||
|
|
||
| ginkgo.By("Verifying the normal priority workload is now pending") | ||
| util.ExpectWorkloadsToBePending(ctx, k8sClient, normalWl) | ||
| }) | ||
| }) | ||
|
|
||
| ginkgo.Context("In a ClusterQueue that is part of a cohort", func() { | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.