github.com/kubeflow/training-operator@v1.7.0/pkg/common/util/util_test.go (about) 1 // Copyright 2022 The Kubeflow Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package util 16 17 import ( 18 "testing" 19 "time" 20 21 corev1 "k8s.io/api/core/v1" 22 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 23 "k8s.io/utils/pointer" 24 25 kubeflowv1 "github.com/kubeflow/training-operator/pkg/apis/kubeflow.org/v1" 26 ) 27 28 func TestDurationUntilExpireTime(t *testing.T) { 29 tests := []struct { 30 name string 31 runPolicy *kubeflowv1.RunPolicy 32 jobStatus kubeflowv1.JobStatus 33 want time.Duration 34 wantErr bool 35 }{ 36 { 37 name: "running job", 38 runPolicy: &kubeflowv1.RunPolicy{}, 39 jobStatus: kubeflowv1.JobStatus{ 40 Conditions: []kubeflowv1.JobCondition{newJobCondition(kubeflowv1.JobRunning)}, 41 }, 42 want: -1, 43 wantErr: false, 44 }, 45 { 46 name: "succeeded job with remaining time 1s", 47 runPolicy: &kubeflowv1.RunPolicy{ 48 TTLSecondsAfterFinished: pointer.Int32(5), 49 }, 50 jobStatus: kubeflowv1.JobStatus{ 51 Conditions: []kubeflowv1.JobCondition{newJobCondition(kubeflowv1.JobSucceeded)}, 52 CompletionTime: &metav1.Time{Time: time.Now().Add(4 * time.Second)}, 53 }, 54 want: 1, 55 wantErr: false, 56 }, 57 { 58 name: "failed job with remaining time 1s", 59 runPolicy: &kubeflowv1.RunPolicy{ 60 TTLSecondsAfterFinished: pointer.Int32(5), 61 }, 62 jobStatus: kubeflowv1.JobStatus{ 63 Conditions: []kubeflowv1.JobCondition{newJobCondition(kubeflowv1.JobFailed)}, 64 CompletionTime: &metav1.Time{Time: time.Now().Add(4 * time.Second)}, 65 }, 66 want: 1, 67 wantErr: false, 68 }, 69 { 70 name: "succeeded job with infinite TTL", 71 runPolicy: &kubeflowv1.RunPolicy{}, 72 jobStatus: kubeflowv1.JobStatus{ 73 Conditions: []kubeflowv1.JobCondition{newJobCondition(kubeflowv1.JobSucceeded)}, 74 CompletionTime: &metav1.Time{Time: time.Now().Add(4 * time.Second)}, 75 }, 76 want: -1, 77 wantErr: false, 78 }, 79 { 80 name: "succeeded job without remaining time", 81 runPolicy: &kubeflowv1.RunPolicy{ 82 TTLSecondsAfterFinished: pointer.Int32(5), 83 }, 84 jobStatus: kubeflowv1.JobStatus{ 85 Conditions: []kubeflowv1.JobCondition{newJobCondition(kubeflowv1.JobSucceeded)}, 86 CompletionTime: &metav1.Time{Time: time.Now().Add(6 * time.Second)}, 87 }, 88 want: 0, 89 wantErr: false, 90 }, 91 { 92 name: "succeeded job with nil completion time error", 93 runPolicy: &kubeflowv1.RunPolicy{ 94 TTLSecondsAfterFinished: pointer.Int32(5), 95 }, 96 jobStatus: kubeflowv1.JobStatus{ 97 Conditions: []kubeflowv1.JobCondition{newJobCondition(kubeflowv1.JobSucceeded)}, 98 }, 99 want: -1, 100 wantErr: true, 101 }, 102 } 103 for _, tt := range tests { 104 t.Run(tt.name, func(t *testing.T) { 105 got, err := DurationUntilExpireTime(tt.runPolicy, tt.jobStatus) 106 if (err != nil) != tt.wantErr { 107 t.Errorf("DurationUntilExpireTime() error = %v, wantErr %v", err, tt.wantErr) 108 return 109 } 110 if got != tt.want { 111 if tt.want < 0 || tt.want >= 0 && tt.want > got { 112 t.Errorf("DurationUntilExpireTime() got = %v, want %v", got, tt.want) 113 } 114 } 115 }) 116 } 117 } 118 119 func newJobCondition(t kubeflowv1.JobConditionType) kubeflowv1.JobCondition { 120 return kubeflowv1.JobCondition{ 121 Type: t, 122 Status: corev1.ConditionTrue, 123 } 124 }