sigs.k8s.io/kueue@v0.6.2/test/integration/controller/core/workload_controller_test.go (about)

     1  /*
     2  Copyright 2022 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package core
    18  
    19  import (
    20  	"fmt"
    21  
    22  	"github.com/google/go-cmp/cmp/cmpopts"
    23  	"github.com/onsi/ginkgo/v2"
    24  	"github.com/onsi/gomega"
    25  	corev1 "k8s.io/api/core/v1"
    26  	apimeta "k8s.io/apimachinery/pkg/api/meta"
    27  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    28  	"sigs.k8s.io/controller-runtime/pkg/client"
    29  
    30  	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta1"
    31  	"sigs.k8s.io/kueue/pkg/constants"
    32  	"sigs.k8s.io/kueue/pkg/util/slices"
    33  	"sigs.k8s.io/kueue/pkg/util/testing"
    34  	"sigs.k8s.io/kueue/pkg/workload"
    35  	"sigs.k8s.io/kueue/test/integration/framework"
    36  	"sigs.k8s.io/kueue/test/util"
    37  )
    38  
    39  // +kubebuilder:docs-gen:collapse=Imports
    40  
    41  var _ = ginkgo.Describe("Workload controller", ginkgo.Ordered, ginkgo.ContinueOnFailure, func() {
    42  	var (
    43  		ns                           *corev1.Namespace
    44  		updatedQueueWorkload         kueue.Workload
    45  		finalQueueWorkload           kueue.Workload
    46  		localQueue                   *kueue.LocalQueue
    47  		wl                           *kueue.Workload
    48  		message                      string
    49  		clusterQueue                 *kueue.ClusterQueue
    50  		workloadPriorityClass        *kueue.WorkloadPriorityClass
    51  		updatedWorkloadPriorityClass *kueue.WorkloadPriorityClass
    52  	)
    53  
    54  	ginkgo.BeforeAll(func() {
    55  		fwk = &framework.Framework{CRDPath: crdPath, WebhookPath: webhookPath}
    56  		cfg = fwk.Init()
    57  		ctx, k8sClient = fwk.RunManager(cfg, managerSetup)
    58  	})
    59  	ginkgo.AfterAll(func() {
    60  		fwk.Teardown()
    61  	})
    62  
    63  	ginkgo.BeforeEach(func() {
    64  		ns = &corev1.Namespace{
    65  			ObjectMeta: metav1.ObjectMeta{
    66  				GenerateName: "core-workload-",
    67  			},
    68  		}
    69  		gomega.Expect(k8sClient.Create(ctx, ns)).To(gomega.Succeed())
    70  	})
    71  
    72  	ginkgo.AfterEach(func() {
    73  		clusterQueue = nil
    74  		localQueue = nil
    75  		updatedQueueWorkload = kueue.Workload{}
    76  	})
    77  
    78  	ginkgo.When("the queue is not defined in the workload", func() {
    79  		ginkgo.AfterEach(func() {
    80  			gomega.Expect(util.DeleteNamespace(ctx, k8sClient, ns)).To(gomega.Succeed())
    81  		})
    82  		ginkgo.It("Should update status when workloads are created", func() {
    83  			wl = testing.MakeWorkload("one", ns.Name).Request(corev1.ResourceCPU, "1").Obj()
    84  			message = fmt.Sprintf("LocalQueue %s doesn't exist", "")
    85  			gomega.Expect(k8sClient.Create(ctx, wl)).To(gomega.Succeed())
    86  			gomega.Eventually(func() int {
    87  				gomega.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(wl), &updatedQueueWorkload)).To(gomega.Succeed())
    88  				return len(updatedQueueWorkload.Status.Conditions)
    89  			}, util.Timeout, util.Interval).Should(gomega.BeComparableTo(1))
    90  			gomega.Expect(updatedQueueWorkload.Status.Conditions[0].Message).To(gomega.BeComparableTo(message))
    91  		})
    92  	})
    93  
    94  	ginkgo.When("the queue doesn't exist", func() {
    95  		ginkgo.AfterEach(func() {
    96  			gomega.Expect(util.DeleteNamespace(ctx, k8sClient, ns)).To(gomega.Succeed())
    97  		})
    98  		ginkgo.It("Should update status when workloads are created", func() {
    99  			wl = testing.MakeWorkload("two", ns.Name).Queue("non-created-queue").Request(corev1.ResourceCPU, "1").Obj()
   100  			message = fmt.Sprintf("LocalQueue %s doesn't exist", "non-created-queue")
   101  			gomega.Expect(k8sClient.Create(ctx, wl)).To(gomega.Succeed())
   102  			gomega.Eventually(func() int {
   103  				gomega.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(wl), &updatedQueueWorkload)).To(gomega.Succeed())
   104  				return len(updatedQueueWorkload.Status.Conditions)
   105  			}, util.Timeout, util.Interval).Should(gomega.BeComparableTo(1))
   106  			gomega.Expect(updatedQueueWorkload.Status.Conditions[0].Message).To(gomega.BeComparableTo(message))
   107  		})
   108  	})
   109  
   110  	ginkgo.When("the clusterqueue doesn't exist", func() {
   111  		ginkgo.BeforeEach(func() {
   112  			localQueue = testing.MakeLocalQueue("queue", ns.Name).ClusterQueue("fooclusterqueue").Obj()
   113  			gomega.Expect(k8sClient.Create(ctx, localQueue)).To(gomega.Succeed())
   114  		})
   115  		ginkgo.AfterEach(func() {
   116  			gomega.Expect(util.DeleteNamespace(ctx, k8sClient, ns)).To(gomega.Succeed())
   117  		})
   118  		ginkgo.It("Should update status when workloads are created", func() {
   119  			wl = testing.MakeWorkload("three", ns.Name).Queue(localQueue.Name).Request(corev1.ResourceCPU, "1").Obj()
   120  			message = fmt.Sprintf("ClusterQueue %s doesn't exist", "fooclusterqueue")
   121  			gomega.Expect(k8sClient.Create(ctx, wl)).To(gomega.Succeed())
   122  			gomega.Eventually(func() []metav1.Condition {
   123  				gomega.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(wl), &updatedQueueWorkload)).To(gomega.Succeed())
   124  				return updatedQueueWorkload.Status.Conditions
   125  			}, util.Timeout, util.Interval).ShouldNot(gomega.BeNil())
   126  			gomega.Expect(updatedQueueWorkload.Status.Conditions[0].Message).To(gomega.BeComparableTo(message))
   127  		})
   128  	})
   129  
   130  	ginkgo.When("the workload is admitted", func() {
   131  		var flavor *kueue.ResourceFlavor
   132  
   133  		ginkgo.BeforeEach(func() {
   134  			flavor = testing.MakeResourceFlavor(flavorOnDemand).Obj()
   135  			gomega.Expect(k8sClient.Create(ctx, flavor)).Should(gomega.Succeed())
   136  			clusterQueue = testing.MakeClusterQueue("cluster-queue").
   137  				ResourceGroup(*testing.MakeFlavorQuotas(flavorOnDemand).
   138  					Resource(resourceGPU, "5", "5").Obj()).
   139  				Cohort("cohort").
   140  				Obj()
   141  			gomega.Expect(k8sClient.Create(ctx, clusterQueue)).To(gomega.Succeed())
   142  			localQueue = testing.MakeLocalQueue("queue", ns.Name).ClusterQueue(clusterQueue.Name).Obj()
   143  			gomega.Expect(k8sClient.Create(ctx, localQueue)).To(gomega.Succeed())
   144  		})
   145  		ginkgo.AfterEach(func() {
   146  			gomega.Expect(util.DeleteNamespace(ctx, k8sClient, ns)).To(gomega.Succeed())
   147  			util.ExpectClusterQueueToBeDeleted(ctx, k8sClient, clusterQueue, true)
   148  			util.ExpectResourceFlavorToBeDeleted(ctx, k8sClient, flavor, true)
   149  		})
   150  	})
   151  
   152  	ginkgo.When("the queue has admission checks", func() {
   153  		var (
   154  			flavor *kueue.ResourceFlavor
   155  			check1 *kueue.AdmissionCheck
   156  			check2 *kueue.AdmissionCheck
   157  		)
   158  
   159  		ginkgo.BeforeEach(func() {
   160  			flavor = testing.MakeResourceFlavor(flavorOnDemand).Obj()
   161  			gomega.Expect(k8sClient.Create(ctx, flavor)).Should(gomega.Succeed())
   162  
   163  			check1 = testing.MakeAdmissionCheck("check1").ControllerName("ctrl").Obj()
   164  			gomega.Expect(k8sClient.Create(ctx, check1)).Should(gomega.Succeed())
   165  			util.SetAdmissionCheckActive(ctx, k8sClient, check1, metav1.ConditionTrue)
   166  
   167  			check2 = testing.MakeAdmissionCheck("check2").ControllerName("ctrl").Obj()
   168  			gomega.Expect(k8sClient.Create(ctx, check2)).Should(gomega.Succeed())
   169  			util.SetAdmissionCheckActive(ctx, k8sClient, check2, metav1.ConditionTrue)
   170  
   171  			clusterQueue = testing.MakeClusterQueue("cluster-queue").
   172  				ResourceGroup(*testing.MakeFlavorQuotas(flavorOnDemand).
   173  					Resource(resourceGPU, "5", "5").Obj()).
   174  				Cohort("cohort").
   175  				AdmissionChecks("check1", "check2").
   176  				Obj()
   177  			gomega.Expect(k8sClient.Create(ctx, clusterQueue)).To(gomega.Succeed())
   178  			localQueue = testing.MakeLocalQueue("queue", ns.Name).ClusterQueue(clusterQueue.Name).Obj()
   179  			gomega.Expect(k8sClient.Create(ctx, localQueue)).To(gomega.Succeed())
   180  		})
   181  		ginkgo.AfterEach(func() {
   182  			gomega.Expect(util.DeleteNamespace(ctx, k8sClient, ns)).To(gomega.Succeed())
   183  			util.ExpectClusterQueueToBeDeleted(ctx, k8sClient, clusterQueue, true)
   184  			util.ExpectAdmissionCheckToBeDeleted(ctx, k8sClient, check2, true)
   185  			util.ExpectAdmissionCheckToBeDeleted(ctx, k8sClient, check1, true)
   186  			util.ExpectResourceFlavorToBeDeleted(ctx, k8sClient, flavor, true)
   187  		})
   188  
   189  		ginkgo.It("the workload should get the AdditionalChecks added", func() {
   190  			wl := testing.MakeWorkload("wl", ns.Name).Queue("queue").Obj()
   191  			wlKey := client.ObjectKeyFromObject(wl)
   192  			createdWl := kueue.Workload{}
   193  			ginkgo.By("creating the workload, the check conditions should be added", func() {
   194  				gomega.Expect(k8sClient.Create(ctx, wl)).To(gomega.Succeed())
   195  
   196  				gomega.Eventually(func() []string {
   197  					gomega.Expect(k8sClient.Get(ctx, wlKey, &createdWl)).To(gomega.Succeed())
   198  					return slices.Map(createdWl.Status.AdmissionChecks, func(c *kueue.AdmissionCheckState) string { return c.Name })
   199  				}, util.Timeout, util.Interval).Should(gomega.ConsistOf("check1", "check2"))
   200  			})
   201  
   202  			ginkgo.By("setting the check conditions", func() {
   203  				gomega.Eventually(func() error {
   204  					gomega.Expect(k8sClient.Get(ctx, wlKey, &createdWl)).To(gomega.Succeed())
   205  					workload.SetAdmissionCheckState(&createdWl.Status.AdmissionChecks, kueue.AdmissionCheckState{
   206  						Name:    "check1",
   207  						State:   kueue.CheckStateReady,
   208  						Message: "check successfully passed",
   209  					})
   210  					workload.SetAdmissionCheckState(&createdWl.Status.AdmissionChecks, kueue.AdmissionCheckState{
   211  						Name:    "check2",
   212  						State:   kueue.CheckStateRetry,
   213  						Message: "check rejected",
   214  					})
   215  					return k8sClient.Status().Update(ctx, &createdWl)
   216  				}, util.Timeout, util.Interval).Should(gomega.Succeed())
   217  			})
   218  
   219  			// save check2 condition
   220  			oldCheck2Cond := workload.FindAdmissionCheck(createdWl.Status.AdmissionChecks, "check2")
   221  			gomega.Expect(oldCheck2Cond).NotTo(gomega.BeNil())
   222  
   223  			ginkgo.By("updating the queue checks, the changes should propagate to the workload", func() {
   224  				createdQueue := kueue.ClusterQueue{}
   225  				queueKey := client.ObjectKeyFromObject(clusterQueue)
   226  				gomega.Eventually(func() error {
   227  					gomega.Expect(k8sClient.Get(ctx, queueKey, &createdQueue)).To(gomega.Succeed())
   228  					createdQueue.Spec.AdmissionChecks = []string{"check2", "check3"}
   229  					return k8sClient.Update(ctx, &createdQueue)
   230  				}, util.Timeout, util.Interval).Should(gomega.Succeed())
   231  
   232  				createdWl := kueue.Workload{}
   233  				gomega.Eventually(func() []string {
   234  					gomega.Expect(k8sClient.Get(ctx, wlKey, &createdWl)).To(gomega.Succeed())
   235  					return slices.Map(createdWl.Status.AdmissionChecks, func(c *kueue.AdmissionCheckState) string { return c.Name })
   236  				}, util.Timeout, util.Interval).Should(gomega.ConsistOf("check2", "check3"))
   237  
   238  				check2Cond := workload.FindAdmissionCheck(createdWl.Status.AdmissionChecks, "check2")
   239  				gomega.Expect(check2Cond).To(gomega.Equal(oldCheck2Cond))
   240  			})
   241  		})
   242  		ginkgo.It("should finish an unadmitted workload with failure when a check is rejected", func() {
   243  			wl := testing.MakeWorkload("wl", ns.Name).Queue("queue").Obj()
   244  			wlKey := client.ObjectKeyFromObject(wl)
   245  			createdWl := kueue.Workload{}
   246  			ginkgo.By("creating the workload, the check conditions should be added", func() {
   247  				gomega.Expect(k8sClient.Create(ctx, wl)).To(gomega.Succeed())
   248  
   249  				gomega.Eventually(func() []string {
   250  					gomega.Expect(k8sClient.Get(ctx, wlKey, &createdWl)).To(gomega.Succeed())
   251  					return slices.Map(createdWl.Status.AdmissionChecks, func(c *kueue.AdmissionCheckState) string { return c.Name })
   252  				}, util.Timeout, util.Interval).Should(gomega.ConsistOf("check1", "check2"))
   253  			})
   254  
   255  			ginkgo.By("setting the check conditions", func() {
   256  				gomega.Eventually(func() error {
   257  					gomega.Expect(k8sClient.Get(ctx, wlKey, &createdWl)).To(gomega.Succeed())
   258  					workload.SetAdmissionCheckState(&createdWl.Status.AdmissionChecks, kueue.AdmissionCheckState{
   259  						Name:    "check1",
   260  						State:   kueue.CheckStateRejected,
   261  						Message: "check rejected",
   262  					})
   263  					return k8sClient.Status().Update(ctx, &createdWl)
   264  				}, util.Timeout, util.Interval).Should(gomega.Succeed())
   265  			})
   266  
   267  			ginkgo.By("checking the finish condition", func() {
   268  				gomega.Eventually(func() *metav1.Condition {
   269  					gomega.Expect(k8sClient.Get(ctx, wlKey, &createdWl)).To(gomega.Succeed())
   270  					return apimeta.FindStatusCondition(createdWl.Status.Conditions, kueue.WorkloadFinished)
   271  				}, util.Timeout, util.Interval).Should(gomega.BeComparableTo(&metav1.Condition{
   272  					Type:    kueue.WorkloadFinished,
   273  					Status:  metav1.ConditionTrue,
   274  					Reason:  "AdmissionChecksRejected",
   275  					Message: "Admission checks [check1] are rejected",
   276  				}, cmpopts.IgnoreFields(metav1.Condition{}, "LastTransitionTime")))
   277  			})
   278  		})
   279  
   280  		ginkgo.It("should evict then finish with failure an admitted workload when a check is rejected", func() {
   281  			wl := testing.MakeWorkload("wl", ns.Name).Queue("queue").Obj()
   282  			wlKey := client.ObjectKeyFromObject(wl)
   283  			createdWl := kueue.Workload{}
   284  			ginkgo.By("creating the workload, the check conditions should be added", func() {
   285  				gomega.Expect(k8sClient.Create(ctx, wl)).To(gomega.Succeed())
   286  
   287  				gomega.Eventually(func() []string {
   288  					gomega.Expect(k8sClient.Get(ctx, wlKey, &createdWl)).To(gomega.Succeed())
   289  					return slices.Map(createdWl.Status.AdmissionChecks, func(c *kueue.AdmissionCheckState) string { return c.Name })
   290  				}, util.Timeout, util.Interval).Should(gomega.ConsistOf("check1", "check2"))
   291  			})
   292  
   293  			ginkgo.By("setting quota reservation and the checks ready, should admit the workload", func() {
   294  				gomega.Eventually(func(g gomega.Gomega) {
   295  					g.Expect(k8sClient.Get(ctx, wlKey, &createdWl)).To(gomega.Succeed())
   296  					g.Expect(util.SetQuotaReservation(ctx, k8sClient, &createdWl, testing.MakeAdmission(clusterQueue.Name).Obj())).To(gomega.Succeed())
   297  				}, util.Timeout, util.Interval).Should(gomega.Succeed())
   298  
   299  				gomega.Eventually(func() error {
   300  					gomega.Expect(k8sClient.Get(ctx, wlKey, &createdWl)).To(gomega.Succeed())
   301  					workload.SetAdmissionCheckState(&createdWl.Status.AdmissionChecks, kueue.AdmissionCheckState{
   302  						Name:    "check1",
   303  						State:   kueue.CheckStateReady,
   304  						Message: "check ready",
   305  					})
   306  					workload.SetAdmissionCheckState(&createdWl.Status.AdmissionChecks, kueue.AdmissionCheckState{
   307  						Name:    "check2",
   308  						State:   kueue.CheckStateReady,
   309  						Message: "check ready",
   310  					})
   311  					return k8sClient.Status().Update(ctx, &createdWl)
   312  				}, util.Timeout, util.Interval).Should(gomega.Succeed())
   313  
   314  				gomega.Eventually(func(g gomega.Gomega) {
   315  					g.Expect(k8sClient.Get(ctx, wlKey, &createdWl)).To(gomega.Succeed())
   316  					g.Expect(createdWl.Status.Conditions).To(gomega.ContainElement(gomega.BeComparableTo(metav1.Condition{
   317  						Type:    kueue.WorkloadAdmitted,
   318  						Status:  metav1.ConditionTrue,
   319  						Reason:  "Admitted",
   320  						Message: "The workload is admitted",
   321  					}, cmpopts.IgnoreFields(metav1.Condition{}, "LastTransitionTime"))))
   322  				}, util.Timeout, util.Interval).Should(gomega.Succeed())
   323  			})
   324  
   325  			ginkgo.By("setting a rejected check conditions the workload should be evicted and admitted condition kept", func() {
   326  				gomega.Eventually(func() error {
   327  					gomega.Expect(k8sClient.Get(ctx, wlKey, &createdWl)).To(gomega.Succeed())
   328  					workload.SetAdmissionCheckState(&createdWl.Status.AdmissionChecks, kueue.AdmissionCheckState{
   329  						Name:    "check1",
   330  						State:   kueue.CheckStateRejected,
   331  						Message: "check rejected",
   332  					})
   333  					return k8sClient.Status().Update(ctx, &createdWl)
   334  				}, util.Timeout, util.Interval).Should(gomega.Succeed())
   335  
   336  				gomega.Eventually(func(g gomega.Gomega) {
   337  					g.Expect(k8sClient.Get(ctx, wlKey, &createdWl)).To(gomega.Succeed())
   338  					g.Expect(createdWl.Status.Conditions).To(gomega.ContainElements(
   339  						gomega.BeComparableTo(metav1.Condition{
   340  							Type:    kueue.WorkloadEvicted,
   341  							Status:  metav1.ConditionTrue,
   342  							Reason:  "AdmissionCheck",
   343  							Message: "At least one admission check is false",
   344  						}, cmpopts.IgnoreFields(metav1.Condition{}, "LastTransitionTime")),
   345  						gomega.BeComparableTo(metav1.Condition{
   346  							Type:    kueue.WorkloadAdmitted,
   347  							Status:  metav1.ConditionTrue,
   348  							Reason:  "Admitted",
   349  							Message: "The workload is admitted",
   350  						}, cmpopts.IgnoreFields(metav1.Condition{}, "LastTransitionTime")),
   351  					))
   352  				}, util.Timeout, util.Interval).Should(gomega.Succeed())
   353  			})
   354  
   355  			ginkgo.By("finishing the eviction the finish condition should be set and admitted condition false", func() {
   356  				util.FinishEvictionForWorkloads(ctx, k8sClient, &createdWl)
   357  				gomega.Eventually(func(g gomega.Gomega) {
   358  					g.Expect(k8sClient.Get(ctx, wlKey, &createdWl)).To(gomega.Succeed())
   359  					g.Expect(createdWl.Status.Conditions).To(gomega.ContainElements(
   360  						gomega.BeComparableTo(metav1.Condition{
   361  							Type:    kueue.WorkloadFinished,
   362  							Status:  metav1.ConditionTrue,
   363  							Reason:  "AdmissionChecksRejected",
   364  							Message: "Admission checks [check1] are rejected",
   365  						}, cmpopts.IgnoreFields(metav1.Condition{}, "LastTransitionTime")),
   366  						gomega.BeComparableTo(metav1.Condition{
   367  							Type:    kueue.WorkloadAdmitted,
   368  							Status:  metav1.ConditionFalse,
   369  							Reason:  "NoReservationNoChecks",
   370  							Message: "The workload has no reservation and not all checks ready",
   371  						}, cmpopts.IgnoreFields(metav1.Condition{}, "LastTransitionTime")),
   372  					))
   373  				}, util.Timeout, util.Interval).Should(gomega.Succeed())
   374  			})
   375  		})
   376  	})
   377  
   378  	ginkgo.When("changing the priority value of PriorityClass doesn't affect the priority of the workload", func() {
   379  		ginkgo.BeforeEach(func() {
   380  			workloadPriorityClass = testing.MakeWorkloadPriorityClass("workload-priority-class").PriorityValue(200).Obj()
   381  			gomega.Expect(k8sClient.Create(ctx, workloadPriorityClass)).To(gomega.Succeed())
   382  
   383  		})
   384  		ginkgo.AfterEach(func() {
   385  			gomega.Expect(util.DeleteNamespace(ctx, k8sClient, ns)).To(gomega.Succeed())
   386  			gomega.Expect(k8sClient.Delete(ctx, workloadPriorityClass)).To(gomega.Succeed())
   387  		})
   388  		ginkgo.It("case of WorkloadPriorityClass", func() {
   389  			ginkgo.By("creating workload")
   390  			wl = testing.MakeWorkload("wl", ns.Name).Queue("lq").Request(corev1.ResourceCPU, "1").
   391  				PriorityClass("workload-priority-class").PriorityClassSource(constants.WorkloadPriorityClassSource).Priority(200).Obj()
   392  			gomega.Expect(k8sClient.Create(ctx, wl)).To(gomega.Succeed())
   393  			gomega.Eventually(func() []metav1.Condition {
   394  				gomega.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(wl), &updatedQueueWorkload)).To(gomega.Succeed())
   395  				return updatedQueueWorkload.Status.Conditions
   396  			}, util.Timeout, util.Interval).ShouldNot(gomega.BeNil())
   397  			initialPriority := int32(200)
   398  			gomega.Expect(updatedQueueWorkload.Spec.Priority).To(gomega.Equal(&initialPriority))
   399  
   400  			ginkgo.By("updating workloadPriorityClass")
   401  			updatedPriority := int32(150)
   402  			updatedWorkloadPriorityClass = workloadPriorityClass.DeepCopy()
   403  			workloadPriorityClass.Value = updatedPriority
   404  			gomega.Expect(k8sClient.Update(ctx, workloadPriorityClass)).To(gomega.Succeed())
   405  			gomega.Eventually(func() int32 {
   406  				gomega.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(workloadPriorityClass), updatedWorkloadPriorityClass)).To(gomega.Succeed())
   407  				return updatedWorkloadPriorityClass.Value
   408  			}, util.Timeout, util.Interval).Should(gomega.Equal(updatedPriority))
   409  			gomega.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(&updatedQueueWorkload), &finalQueueWorkload)).To(gomega.Succeed())
   410  			gomega.Expect(finalQueueWorkload.Spec.Priority).To(gomega.Equal(&initialPriority))
   411  		})
   412  	})
   413  })