Skip to content

Commit b10b773

Browse files
committed
Handle other Slice statuses.
1 parent ac991c7 commit b10b773

File tree

4 files changed

+178
-10
lines changed

4 files changed

+178
-10
lines changed

slice/internal/controller/workload_controller.go

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -246,17 +246,33 @@ func (r *WorkloadReconciler) updateWorkloadAdmissionCheckStatus(ctx context.Cont
246246

247247
// syncAdmissionCheckStatus syncs the admission check status with the state of the slice.
248248
func (r *WorkloadReconciler) syncAdmissionCheckStatus(ctx context.Context, wl *kueue.Workload, ac *kueue.AdmissionCheckState, slice *v1alpha1.Slice) error {
249-
if !meta.IsStatusConditionTrue(slice.Status.Conditions, string(v1alpha1.Ready)) {
250-
return nil
251-
}
252249
originalState := ac.State
253-
ac.State = kueue.CheckStateReady
254-
ac.Message = fmt.Sprintf("The Slice %q has been created and configured", slice.Name)
250+
251+
errCond := meta.FindStatusCondition(slice.Status.Conditions, string(v1alpha1.Error))
252+
253+
switch {
254+
case meta.IsStatusConditionTrue(slice.Status.Conditions, string(v1alpha1.Forming)):
255+
ac.Message = fmt.Sprintf("The Slice %q is being formed", slice.Name)
256+
case meta.IsStatusConditionTrue(slice.Status.Conditions, string(v1alpha1.Ready)):
257+
ac.State = kueue.CheckStateReady
258+
ac.Message = fmt.Sprintf("The Slice %q is fully operational", slice.Name)
259+
case meta.IsStatusConditionTrue(slice.Status.Conditions, string(v1alpha1.Degraded)):
260+
ac.State = kueue.CheckStateReady
261+
ac.Message = fmt.Sprintf("The Slice %q is running with reduced capacity or performance", slice.Name)
262+
case meta.IsStatusConditionTrue(slice.Status.Conditions, string(v1alpha1.Deformed)):
263+
ac.State = kueue.CheckStateRejected
264+
ac.Message = fmt.Sprintf("The Slice %q is being torn down", slice.Name)
265+
case errCond != nil && errCond.Status == metav1.ConditionTrue:
266+
ac.State = kueue.CheckStateRejected
267+
ac.Message = fmt.Sprintf("The Slice %q is not operational due to an error: %s", slice.Name, errCond.Message)
268+
}
269+
255270
err := r.updateWorkloadAdmissionCheckStatus(ctx, wl, ac)
256-
if err == nil {
257-
message := fmt.Sprintf("Admission check %q updated state from %q to %q", ac.Name, originalState, kueue.CheckStateReady)
271+
if err == nil && originalState != ac.State {
272+
message := fmt.Sprintf("Admission check %q updated state from %q to %q", ac.Name, originalState, ac.State)
258273
r.record.Event(wl, corev1.EventTypeNormal, AdmissionCheckUpdatedEventType, message)
259274
}
275+
260276
return err
261277
}
262278

slice/internal/controller/workload_controller_test.go

Lines changed: 106 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,26 @@ func TestWorkloadReconciler(t *testing.T) {
251251
},
252252
},
253253
},
254+
"should update the Workload AdmissionCheckState when the Slice status is changed to Forming": {
255+
request: baseRequest,
256+
objs: []client.Object{
257+
baseAdmissionCheckWrapper.DeepCopy(),
258+
baseWorkloadWrapper.Finalizers(SliceControllerName).DeepCopy(),
259+
baseSliceWrapper.Clone().Forming().Obj(),
260+
},
261+
wantWorkloads: []kueue.Workload{
262+
*baseWorkloadWrapper.Clone().
263+
Finalizers(SliceControllerName).
264+
AdmissionCheck(kueue.AdmissionCheckState{
265+
Name: kueue.AdmissionCheckReference(baseAdmissionCheckName),
266+
State: kueue.CheckStatePending,
267+
LastTransitionTime: metav1.NewTime(now),
268+
Message: fmt.Sprintf(`The Slice %q is being formed`, baseWorkloadName),
269+
}).
270+
Obj(),
271+
},
272+
wantSlices: []slice.Slice{*baseSliceWrapper.Clone().Forming().Obj()},
273+
},
254274
"should update the Workload AdmissionCheckState when the Slice status is changed to Ready": {
255275
request: baseRequest,
256276
objs: []client.Object{
@@ -265,7 +285,7 @@ func TestWorkloadReconciler(t *testing.T) {
265285
Name: kueue.AdmissionCheckReference(baseAdmissionCheckName),
266286
State: kueue.CheckStateReady,
267287
LastTransitionTime: metav1.NewTime(now),
268-
Message: fmt.Sprintf(`The Slice %q has been created and configured`, baseWorkloadName),
288+
Message: fmt.Sprintf(`The Slice %q is fully operational`, baseWorkloadName),
269289
}).
270290
Obj(),
271291
},
@@ -279,6 +299,90 @@ func TestWorkloadReconciler(t *testing.T) {
279299
},
280300
},
281301
},
302+
"should update the Workload AdmissionCheckState when the Slice status is changed to Degraded": {
303+
request: baseRequest,
304+
objs: []client.Object{
305+
baseAdmissionCheckWrapper.DeepCopy(),
306+
baseWorkloadWrapper.Finalizers(SliceControllerName).DeepCopy(),
307+
baseSliceWrapper.Clone().Degraded().Obj(),
308+
},
309+
wantWorkloads: []kueue.Workload{
310+
*baseWorkloadWrapper.Clone().
311+
Finalizers(SliceControllerName).
312+
AdmissionCheck(kueue.AdmissionCheckState{
313+
Name: kueue.AdmissionCheckReference(baseAdmissionCheckName),
314+
State: kueue.CheckStateReady,
315+
LastTransitionTime: metav1.NewTime(now),
316+
Message: fmt.Sprintf(`The Slice %q is running with reduced capacity or performance`, baseWorkloadName),
317+
}).
318+
Obj(),
319+
},
320+
wantSlices: []slice.Slice{*baseSliceWrapper.Clone().Degraded().Obj()},
321+
wantEvents: []utiltesting.EventRecord{
322+
{
323+
Key: client.ObjectKeyFromObject(baseWorkloadWrapper),
324+
EventType: corev1.EventTypeNormal,
325+
Reason: AdmissionCheckUpdatedEventType,
326+
Message: fmt.Sprintf(`Admission check %q updated state from "Pending" to "Ready"`, baseAdmissionCheckName),
327+
},
328+
},
329+
},
330+
"should update the Workload AdmissionCheckState when the Slice status is changed to Deformed": {
331+
request: baseRequest,
332+
objs: []client.Object{
333+
baseAdmissionCheckWrapper.DeepCopy(),
334+
baseWorkloadWrapper.Finalizers(SliceControllerName).DeepCopy(),
335+
baseSliceWrapper.Clone().Deformed().Obj(),
336+
},
337+
wantWorkloads: []kueue.Workload{
338+
*baseWorkloadWrapper.Clone().
339+
Finalizers(SliceControllerName).
340+
AdmissionCheck(kueue.AdmissionCheckState{
341+
Name: kueue.AdmissionCheckReference(baseAdmissionCheckName),
342+
State: kueue.CheckStateRejected,
343+
LastTransitionTime: metav1.NewTime(now),
344+
Message: fmt.Sprintf(`The Slice %q is being torn down`, baseWorkloadName),
345+
}).
346+
Obj(),
347+
},
348+
wantSlices: []slice.Slice{*baseSliceWrapper.Clone().Deformed().Obj()},
349+
wantEvents: []utiltesting.EventRecord{
350+
{
351+
Key: client.ObjectKeyFromObject(baseWorkloadWrapper),
352+
EventType: corev1.EventTypeNormal,
353+
Reason: AdmissionCheckUpdatedEventType,
354+
Message: fmt.Sprintf(`Admission check %q updated state from "Pending" to "Rejected"`, baseAdmissionCheckName),
355+
},
356+
},
357+
},
358+
"should update the Workload AdmissionCheckState when the Slice status is changed to Error": {
359+
request: baseRequest,
360+
objs: []client.Object{
361+
baseAdmissionCheckWrapper.DeepCopy(),
362+
baseWorkloadWrapper.Finalizers(SliceControllerName).DeepCopy(),
363+
baseSliceWrapper.Clone().Error().Obj(),
364+
},
365+
wantWorkloads: []kueue.Workload{
366+
*baseWorkloadWrapper.Clone().
367+
Finalizers(SliceControllerName).
368+
AdmissionCheck(kueue.AdmissionCheckState{
369+
Name: kueue.AdmissionCheckReference(baseAdmissionCheckName),
370+
State: kueue.CheckStateRejected,
371+
LastTransitionTime: metav1.NewTime(now),
372+
Message: fmt.Sprintf(`The Slice %q is not operational due to an error: Error by test`, baseWorkloadName),
373+
}).
374+
Obj(),
375+
},
376+
wantSlices: []slice.Slice{*baseSliceWrapper.Clone().Error().Obj()},
377+
wantEvents: []utiltesting.EventRecord{
378+
{
379+
Key: client.ObjectKeyFromObject(baseWorkloadWrapper),
380+
EventType: corev1.EventTypeNormal,
381+
Reason: AdmissionCheckUpdatedEventType,
382+
Message: fmt.Sprintf(`Admission check %q updated state from "Pending" to "Rejected"`, baseAdmissionCheckName),
383+
},
384+
},
385+
},
282386
"should use the first AdmissionCheck if more than one is found": {
283387
request: baseRequest,
284388
objs: []client.Object{
@@ -294,7 +398,7 @@ func TestWorkloadReconciler(t *testing.T) {
294398
Name: kueue.AdmissionCheckReference(baseAdmissionCheckName),
295399
State: kueue.CheckStateReady,
296400
LastTransitionTime: metav1.NewTime(now),
297-
Message: fmt.Sprintf(`The Slice %q has been created and configured`, baseWorkloadName),
401+
Message: fmt.Sprintf(`The Slice %q is fully operational`, baseWorkloadName),
298402
}).
299403
Obj(),
300404
},

slice/internal/util/testing/wrappers.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,54 @@ func (s *SliceWrapper) Ready() *SliceWrapper {
228228
return s
229229
}
230230

231+
func (s *SliceWrapper) Forming() *SliceWrapper {
232+
cond := metav1.Condition{
233+
Type: string(v1alpha1.Forming),
234+
Status: metav1.ConditionTrue,
235+
LastTransitionTime: metav1.Now(),
236+
Reason: "ByTest",
237+
Message: "Forming by test",
238+
}
239+
apimeta.SetStatusCondition(&s.Status.Conditions, cond)
240+
return s
241+
}
242+
243+
func (s *SliceWrapper) Deformed() *SliceWrapper {
244+
cond := metav1.Condition{
245+
Type: string(v1alpha1.Deformed),
246+
Status: metav1.ConditionTrue,
247+
LastTransitionTime: metav1.Now(),
248+
Reason: "ByTest",
249+
Message: "Deformed by test",
250+
}
251+
apimeta.SetStatusCondition(&s.Status.Conditions, cond)
252+
return s
253+
}
254+
255+
func (s *SliceWrapper) Degraded() *SliceWrapper {
256+
cond := metav1.Condition{
257+
Type: string(v1alpha1.Degraded),
258+
Status: metav1.ConditionTrue,
259+
LastTransitionTime: metav1.Now(),
260+
Reason: "ByTest",
261+
Message: "Degraded by test",
262+
}
263+
apimeta.SetStatusCondition(&s.Status.Conditions, cond)
264+
return s
265+
}
266+
267+
func (s *SliceWrapper) Error() *SliceWrapper {
268+
cond := metav1.Condition{
269+
Type: string(v1alpha1.Error),
270+
Status: metav1.ConditionTrue,
271+
LastTransitionTime: metav1.Now(),
272+
Reason: "ByTest",
273+
Message: "Error by test",
274+
}
275+
apimeta.SetStatusCondition(&s.Status.Conditions, cond)
276+
return s
277+
}
278+
231279
func AppendOwnerReference(obj client.Object, gvk schema.GroupVersionKind, name, uid string, controller, blockDeletion *bool) {
232280
obj.SetOwnerReferences(append(obj.GetOwnerReferences(), metav1.OwnerReference{
233281
APIVersion: gvk.GroupVersion().String(),

slice/test/e2e/jobset_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ var _ = ginkgo.Describe("JobSet", func() {
235235
g.Expect(createdWorkload.Status.AdmissionChecks).Should(gomega.BeComparableTo([]kueue.AdmissionCheckState{{
236236
Name: kueue.AdmissionCheckReference(ac.Name),
237237
State: kueue.CheckStateReady,
238-
Message: fmt.Sprintf("The Slice %q has been created and configured", createdWorkload.Name),
238+
Message: fmt.Sprintf("The Slice %q is fully operational", createdWorkload.Name),
239239
}}, cmpopts.IgnoreFields(kueue.AdmissionCheckState{}, "LastTransitionTime", "PodSetUpdates")))
240240
}, utils.LongTimeout, utils.Timeout).Should(gomega.Succeed())
241241
})

0 commit comments

Comments
 (0)