Skip to content

Commit 2c5a8cd

Browse files
api/kueue/v1beta1: add unit tests for workload conversion (#7546)
Related to #7394
1 parent 441e8f3 commit 2c5a8cd

File tree

1 file changed

+285
-0
lines changed

1 file changed

+285
-0
lines changed
Lines changed: 285 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,285 @@
1+
/*
2+
Copyright 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 v1beta1
18+
19+
import (
20+
"testing"
21+
22+
"github.com/google/go-cmp/cmp"
23+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
24+
"k8s.io/utils/ptr"
25+
26+
"sigs.k8s.io/kueue/apis/kueue/v1beta2"
27+
)
28+
29+
func TestWorkloadConvertTo(t *testing.T) {
30+
defaultObjectMeta := metav1.ObjectMeta{
31+
Name: "test-workload",
32+
Namespace: "default",
33+
}
34+
35+
testCases := map[string]struct {
36+
input *Workload
37+
expected *v1beta2.Workload
38+
}{
39+
"nil AccumulatedPastExexcutionTimeSeconds": {
40+
input: &Workload{
41+
ObjectMeta: defaultObjectMeta,
42+
Status: WorkloadStatus{
43+
AccumulatedPastExexcutionTimeSeconds: nil,
44+
},
45+
},
46+
expected: &v1beta2.Workload{
47+
ObjectMeta: defaultObjectMeta,
48+
Status: v1beta2.WorkloadStatus{
49+
AccumulatedPastExecutionTimeSeconds: nil,
50+
},
51+
},
52+
},
53+
"zero AccumulatedPastExexcutionTimeSeconds": {
54+
input: &Workload{
55+
ObjectMeta: defaultObjectMeta,
56+
Status: WorkloadStatus{
57+
AccumulatedPastExexcutionTimeSeconds: ptr.To[int32](0),
58+
},
59+
},
60+
expected: &v1beta2.Workload{
61+
ObjectMeta: defaultObjectMeta,
62+
Status: v1beta2.WorkloadStatus{
63+
AccumulatedPastExecutionTimeSeconds: ptr.To[int32](0),
64+
},
65+
},
66+
},
67+
"non-zero AccumulatedPastExexcutionTimeSeconds": {
68+
input: &Workload{
69+
ObjectMeta: defaultObjectMeta,
70+
Status: WorkloadStatus{
71+
AccumulatedPastExexcutionTimeSeconds: ptr.To[int32](3600),
72+
},
73+
},
74+
expected: &v1beta2.Workload{
75+
ObjectMeta: defaultObjectMeta,
76+
Status: v1beta2.WorkloadStatus{
77+
AccumulatedPastExecutionTimeSeconds: ptr.To[int32](3600),
78+
},
79+
},
80+
},
81+
"with conditions and other fields": {
82+
input: &Workload{
83+
ObjectMeta: defaultObjectMeta,
84+
Status: WorkloadStatus{
85+
Conditions: []metav1.Condition{
86+
{
87+
Type: "Admitted",
88+
Status: metav1.ConditionTrue,
89+
Reason: "AdmittedByClusterQueue",
90+
},
91+
},
92+
AccumulatedPastExexcutionTimeSeconds: ptr.To[int32](7200),
93+
},
94+
},
95+
expected: &v1beta2.Workload{
96+
ObjectMeta: defaultObjectMeta,
97+
Status: v1beta2.WorkloadStatus{
98+
Conditions: []metav1.Condition{
99+
{
100+
Type: "Admitted",
101+
Status: metav1.ConditionTrue,
102+
Reason: "AdmittedByClusterQueue",
103+
},
104+
},
105+
AccumulatedPastExecutionTimeSeconds: ptr.To[int32](7200),
106+
},
107+
},
108+
},
109+
}
110+
111+
for name, tc := range testCases {
112+
t.Run(name, func(t *testing.T) {
113+
result := &v1beta2.Workload{}
114+
if err := tc.input.ConvertTo(result); err != nil {
115+
t.Fatalf("ConvertTo failed: %v", err)
116+
}
117+
if diff := cmp.Diff(tc.expected, result); diff != "" {
118+
t.Errorf("unexpected conversion result (-want +got):\n%s", diff)
119+
}
120+
})
121+
}
122+
}
123+
124+
func TestWorkloadConvertFrom(t *testing.T) {
125+
defaultObjectMeta := metav1.ObjectMeta{
126+
Name: "test-workload",
127+
Namespace: "default",
128+
}
129+
130+
testCases := map[string]struct {
131+
input *v1beta2.Workload
132+
expected *Workload
133+
}{
134+
"nil AccumulatedPastExecutionTimeSeconds": {
135+
input: &v1beta2.Workload{
136+
ObjectMeta: defaultObjectMeta,
137+
Status: v1beta2.WorkloadStatus{
138+
AccumulatedPastExecutionTimeSeconds: nil,
139+
},
140+
},
141+
expected: &Workload{
142+
ObjectMeta: defaultObjectMeta,
143+
Status: WorkloadStatus{
144+
AccumulatedPastExexcutionTimeSeconds: nil,
145+
},
146+
},
147+
},
148+
"zero AccumulatedPastExecutionTimeSeconds": {
149+
input: &v1beta2.Workload{
150+
ObjectMeta: defaultObjectMeta,
151+
Status: v1beta2.WorkloadStatus{
152+
AccumulatedPastExecutionTimeSeconds: ptr.To[int32](0),
153+
},
154+
},
155+
expected: &Workload{
156+
ObjectMeta: defaultObjectMeta,
157+
Status: WorkloadStatus{
158+
AccumulatedPastExexcutionTimeSeconds: ptr.To[int32](0),
159+
},
160+
},
161+
},
162+
"non-zero AccumulatedPastExecutionTimeSeconds": {
163+
input: &v1beta2.Workload{
164+
ObjectMeta: defaultObjectMeta,
165+
Status: v1beta2.WorkloadStatus{
166+
AccumulatedPastExecutionTimeSeconds: ptr.To[int32](3600),
167+
},
168+
},
169+
expected: &Workload{
170+
ObjectMeta: defaultObjectMeta,
171+
Status: WorkloadStatus{
172+
AccumulatedPastExexcutionTimeSeconds: ptr.To[int32](3600),
173+
},
174+
},
175+
},
176+
"with conditions and other fields": {
177+
input: &v1beta2.Workload{
178+
ObjectMeta: defaultObjectMeta,
179+
Status: v1beta2.WorkloadStatus{
180+
Conditions: []metav1.Condition{
181+
{
182+
Type: "Finished",
183+
Status: metav1.ConditionTrue,
184+
Reason: "JobFinished",
185+
},
186+
},
187+
AccumulatedPastExecutionTimeSeconds: ptr.To[int32](1800),
188+
},
189+
},
190+
expected: &Workload{
191+
ObjectMeta: defaultObjectMeta,
192+
Status: WorkloadStatus{
193+
Conditions: []metav1.Condition{
194+
{
195+
Type: "Finished",
196+
Status: metav1.ConditionTrue,
197+
Reason: "JobFinished",
198+
},
199+
},
200+
AccumulatedPastExexcutionTimeSeconds: ptr.To[int32](1800),
201+
},
202+
},
203+
},
204+
}
205+
206+
for name, tc := range testCases {
207+
t.Run(name, func(t *testing.T) {
208+
result := &Workload{}
209+
if err := result.ConvertFrom(tc.input); err != nil {
210+
t.Fatalf("ConvertFrom failed: %v", err)
211+
}
212+
if diff := cmp.Diff(tc.expected, result); diff != "" {
213+
t.Errorf("unexpected conversion result (-want +got):\n%s", diff)
214+
}
215+
})
216+
}
217+
}
218+
219+
func TestWorkloadConversion_RoundTrip(t *testing.T) {
220+
testCases := map[string]struct {
221+
v1beta1Obj *Workload
222+
}{
223+
"complete Workload with AccumulatedPastExexcutionTimeSeconds": {
224+
v1beta1Obj: &Workload{
225+
ObjectMeta: metav1.ObjectMeta{
226+
Name: "test-workload",
227+
Namespace: "default",
228+
},
229+
Status: WorkloadStatus{
230+
Conditions: []metav1.Condition{
231+
{
232+
Type: "Admitted",
233+
Status: metav1.ConditionTrue,
234+
Reason: "AdmittedByClusterQueue",
235+
},
236+
},
237+
AccumulatedPastExexcutionTimeSeconds: ptr.To[int32](5400),
238+
},
239+
},
240+
},
241+
"Workload with nil AccumulatedPastExexcutionTimeSeconds": {
242+
v1beta1Obj: &Workload{
243+
ObjectMeta: metav1.ObjectMeta{
244+
Name: "simple-workload",
245+
Namespace: "test-ns",
246+
},
247+
Status: WorkloadStatus{
248+
AccumulatedPastExexcutionTimeSeconds: nil,
249+
},
250+
},
251+
},
252+
"Workload with zero AccumulatedPastExexcutionTimeSeconds": {
253+
v1beta1Obj: &Workload{
254+
ObjectMeta: metav1.ObjectMeta{
255+
Name: "zero-workload",
256+
Namespace: "test-ns",
257+
},
258+
Status: WorkloadStatus{
259+
AccumulatedPastExexcutionTimeSeconds: ptr.To[int32](0),
260+
},
261+
},
262+
},
263+
}
264+
265+
for name, tc := range testCases {
266+
t.Run(name, func(t *testing.T) {
267+
// Convert v1beta1 -> v1beta2
268+
v1beta2Obj := &v1beta2.Workload{}
269+
if err := tc.v1beta1Obj.ConvertTo(v1beta2Obj); err != nil {
270+
t.Fatalf("ConvertTo failed: %v", err)
271+
}
272+
273+
// Convert v1beta2 -> v1beta1 (round-trip)
274+
roundTripped := &Workload{}
275+
if err := roundTripped.ConvertFrom(v1beta2Obj); err != nil {
276+
t.Fatalf("ConvertFrom failed: %v", err)
277+
}
278+
279+
// Verify round-trip
280+
if diff := cmp.Diff(tc.v1beta1Obj, roundTripped); diff != "" {
281+
t.Errorf("round-trip conversion produced diff (-original +roundtripped):\n%s", diff)
282+
}
283+
})
284+
}
285+
}

0 commit comments

Comments
 (0)