@@ -23,6 +23,7 @@ import (
2323 . "github.com/onsi/gomega"
2424 v1 "k8s.io/api/core/v1"
2525 "k8s.io/apimachinery/pkg/api/meta"
26+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2627 "k8s.io/apimachinery/pkg/types"
2728 "k8s.io/client-go/tools/record"
2829 "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
@@ -173,7 +174,7 @@ var _ = Describe("AppWrapper Controller", func() {
173174 })
174175
175176 It ("Happy Path Lifecycle" , func () {
176- advanceToResuming (pod (100 , 1 ), pod (100 , 0 ))
177+ advanceToResuming (pod (100 , 1 , true ), pod (100 , 0 , false ))
177178 beginRunning ()
178179 fullyRunning ()
179180
@@ -223,7 +224,7 @@ var _ = Describe("AppWrapper Controller", func() {
223224 })
224225
225226 It ("Running Workloads can be Suspended" , func () {
226- advanceToResuming (pod (100 , 0 ), pod (100 , 1 ))
227+ advanceToResuming (pod (100 , 0 , false ), pod (100 , 1 , true ))
227228 beginRunning ()
228229 fullyRunning ()
229230
@@ -262,7 +263,7 @@ var _ = Describe("AppWrapper Controller", func() {
262263 })
263264
264265 It ("A Pod Failure leads to a failed AppWrapper" , func () {
265- advanceToResuming (pod (100 , 0 ), pod (100 , 0 ))
266+ advanceToResuming (pod (100 , 0 , false ), pod (100 , 0 , true ))
266267 beginRunning ()
267268 fullyRunning ()
268269
@@ -300,7 +301,7 @@ var _ = Describe("AppWrapper Controller", func() {
300301 })
301302
302303 It ("Failure during resource creation leads to a failed AppWrapper" , func () {
303- advanceToResuming (pod (100 , 0 ), malformedPod (100 ))
304+ advanceToResuming (pod (100 , 0 , false ), malformedPod (100 ))
304305
305306 By ("Reconciling: Resuming -> Failed" )
306307 _ , err := awReconciler .Reconcile (ctx , reconcile.Request {NamespacedName : awName })
@@ -317,5 +318,120 @@ var _ = Describe("AppWrapper Controller", func() {
317318 Expect (err ).NotTo (HaveOccurred ())
318319 Expect (podStatus .pending ).Should (Equal (int32 (1 )))
319320 })
321+ })
322+
323+ var _ = Describe ("AppWrapper Annotations" , func () {
324+ var awReconciler * AppWrapperReconciler
325+
326+ BeforeEach (func () {
327+ awReconciler = & AppWrapperReconciler {
328+ Client : k8sClient ,
329+ Recorder : & record.FakeRecorder {},
330+ Scheme : k8sClient .Scheme (),
331+ Config : config .NewAppWrapperConfig (),
332+ }
333+ })
334+
335+ It ("Unannotated appwrappers use defaults" , func () {
336+ aw := & workloadv1beta2.AppWrapper {}
337+ Expect (awReconciler .admissionGraceDuration (ctx , aw )).Should (Equal (awReconciler .Config .FaultTolerance .AdmissionGracePeriod ))
338+ Expect (awReconciler .warmupGraceDuration (ctx , aw )).Should (Equal (awReconciler .Config .FaultTolerance .WarmupGracePeriod ))
339+ Expect (awReconciler .failureGraceDuration (ctx , aw )).Should (Equal (awReconciler .Config .FaultTolerance .FailureGracePeriod ))
340+ Expect (awReconciler .retryLimit (ctx , aw )).Should (Equal (awReconciler .Config .FaultTolerance .RetryLimit ))
341+ Expect (awReconciler .retryPauseDuration (ctx , aw )).Should (Equal (awReconciler .Config .FaultTolerance .RetryPausePeriod ))
342+ Expect (awReconciler .forcefulDeletionGraceDuration (ctx , aw )).Should (Equal (awReconciler .Config .FaultTolerance .ForcefulDeletionGracePeriod ))
343+ Expect (awReconciler .deletionOnFailureGraceDuration (ctx , aw )).Should (Equal (0 * time .Second ))
344+ Expect (awReconciler .timeToLiveAfterSucceededDuration (ctx , aw )).Should (Equal (awReconciler .Config .FaultTolerance .SuccessTTL ))
345+ })
346+
347+ It ("Valid annotations override defaults" , func () {
348+ allowed := 10 * time .Second
349+ aw := & workloadv1beta2.AppWrapper {
350+ ObjectMeta : metav1.ObjectMeta {
351+ Annotations : map [string ]string {
352+ workloadv1beta2 .AdmissionGracePeriodDurationAnnotation : allowed .String (),
353+ workloadv1beta2 .WarmupGracePeriodDurationAnnotation : allowed .String (),
354+ workloadv1beta2 .FailureGracePeriodDurationAnnotation : allowed .String (),
355+ workloadv1beta2 .RetryPausePeriodDurationAnnotation : allowed .String (),
356+ workloadv1beta2 .RetryLimitAnnotation : "101" ,
357+ workloadv1beta2 .ForcefulDeletionGracePeriodAnnotation : allowed .String (),
358+ workloadv1beta2 .DeletionOnFailureGracePeriodAnnotation : allowed .String (),
359+ workloadv1beta2 .SuccessTTLAnnotation : allowed .String (),
360+ },
361+ },
362+ }
363+ Expect (awReconciler .admissionGraceDuration (ctx , aw )).Should (Equal (allowed ))
364+ Expect (awReconciler .warmupGraceDuration (ctx , aw )).Should (Equal (allowed ))
365+ Expect (awReconciler .failureGraceDuration (ctx , aw )).Should (Equal (allowed ))
366+ Expect (awReconciler .retryLimit (ctx , aw )).Should (Equal (int32 (101 )))
367+ Expect (awReconciler .retryPauseDuration (ctx , aw )).Should (Equal (allowed ))
368+ Expect (awReconciler .forcefulDeletionGraceDuration (ctx , aw )).Should (Equal (allowed ))
369+ Expect (awReconciler .deletionOnFailureGraceDuration (ctx , aw )).Should (Equal (allowed ))
370+ Expect (awReconciler .timeToLiveAfterSucceededDuration (ctx , aw )).Should (Equal (allowed ))
371+ })
372+
373+ It ("Malformed annotations use defaults" , func () {
374+ malformed := "222badTime"
375+ aw := & workloadv1beta2.AppWrapper {
376+ ObjectMeta : metav1.ObjectMeta {
377+ Annotations : map [string ]string {
378+ workloadv1beta2 .AdmissionGracePeriodDurationAnnotation : malformed ,
379+ workloadv1beta2 .WarmupGracePeriodDurationAnnotation : malformed ,
380+ workloadv1beta2 .FailureGracePeriodDurationAnnotation : malformed ,
381+ workloadv1beta2 .RetryPausePeriodDurationAnnotation : malformed ,
382+ workloadv1beta2 .RetryLimitAnnotation : "abc" ,
383+ workloadv1beta2 .ForcefulDeletionGracePeriodAnnotation : malformed ,
384+ workloadv1beta2 .DeletionOnFailureGracePeriodAnnotation : malformed ,
385+ workloadv1beta2 .SuccessTTLAnnotation : malformed ,
386+ },
387+ },
388+ }
389+ Expect (awReconciler .admissionGraceDuration (ctx , aw )).Should (Equal (awReconciler .Config .FaultTolerance .AdmissionGracePeriod ))
390+ Expect (awReconciler .warmupGraceDuration (ctx , aw )).Should (Equal (awReconciler .Config .FaultTolerance .WarmupGracePeriod ))
391+ Expect (awReconciler .failureGraceDuration (ctx , aw )).Should (Equal (awReconciler .Config .FaultTolerance .FailureGracePeriod ))
392+ Expect (awReconciler .retryLimit (ctx , aw )).Should (Equal (awReconciler .Config .FaultTolerance .RetryLimit ))
393+ Expect (awReconciler .retryPauseDuration (ctx , aw )).Should (Equal (awReconciler .Config .FaultTolerance .RetryPausePeriod ))
394+ Expect (awReconciler .forcefulDeletionGraceDuration (ctx , aw )).Should (Equal (awReconciler .Config .FaultTolerance .ForcefulDeletionGracePeriod ))
395+ Expect (awReconciler .deletionOnFailureGraceDuration (ctx , aw )).Should (Equal (0 * time .Second ))
396+ Expect (awReconciler .timeToLiveAfterSucceededDuration (ctx , aw )).Should (Equal (awReconciler .Config .FaultTolerance .SuccessTTL ))
397+ })
398+
399+ It ("Out of bounds annotations are clipped" , func () {
400+ negative := - 10 * time .Minute
401+ tooLong := 2 * awReconciler .Config .FaultTolerance .GracePeriodMaximum
402+ aw := & workloadv1beta2.AppWrapper {
403+ ObjectMeta : metav1.ObjectMeta {
404+ Annotations : map [string ]string {
405+ workloadv1beta2 .AdmissionGracePeriodDurationAnnotation : negative .String (),
406+ workloadv1beta2 .WarmupGracePeriodDurationAnnotation : tooLong .String (),
407+ workloadv1beta2 .FailureGracePeriodDurationAnnotation : tooLong .String (),
408+ workloadv1beta2 .RetryPausePeriodDurationAnnotation : negative .String (),
409+ workloadv1beta2 .ForcefulDeletionGracePeriodAnnotation : tooLong .String (),
410+ workloadv1beta2 .DeletionOnFailureGracePeriodAnnotation : tooLong .String (),
411+ workloadv1beta2 .SuccessTTLAnnotation : (awReconciler .Config .FaultTolerance .SuccessTTL + 10 * time .Second ).String (),
412+ },
413+ },
414+ }
415+ Expect (awReconciler .admissionGraceDuration (ctx , aw )).Should (Equal (0 * time .Second ))
416+ Expect (awReconciler .warmupGraceDuration (ctx , aw )).Should (Equal (awReconciler .Config .FaultTolerance .GracePeriodMaximum ))
417+ Expect (awReconciler .failureGraceDuration (ctx , aw )).Should (Equal (awReconciler .Config .FaultTolerance .GracePeriodMaximum ))
418+ Expect (awReconciler .retryPauseDuration (ctx , aw )).Should (Equal (0 * time .Second ))
419+ Expect (awReconciler .forcefulDeletionGraceDuration (ctx , aw )).Should (Equal (awReconciler .Config .FaultTolerance .GracePeriodMaximum ))
420+ Expect (awReconciler .deletionOnFailureGraceDuration (ctx , aw )).Should (Equal (awReconciler .Config .FaultTolerance .GracePeriodMaximum ))
421+ Expect (awReconciler .timeToLiveAfterSucceededDuration (ctx , aw )).Should (Equal (awReconciler .Config .FaultTolerance .SuccessTTL ))
422+ })
423+
424+ It ("Parsing of terminal exits codes" , func () {
425+ aw := & workloadv1beta2.AppWrapper {
426+ ObjectMeta : metav1.ObjectMeta {
427+ Annotations : map [string ]string {
428+ workloadv1beta2 .TerminalExitCodesAnnotation : "3,10,abc,42" ,
429+ workloadv1beta2 .RetryableExitCodesAnnotation : "x,10,20" ,
430+ },
431+ },
432+ }
433+ Expect (awReconciler .terminalExitCodes (ctx , aw )).Should (Equal ([]int {3 , 10 , 42 }))
434+ Expect (awReconciler .retryableExitCodes (ctx , aw )).Should (Equal ([]int {10 , 20 }))
435+ })
320436
321437})
0 commit comments