1
16
17 package job
18
19 import (
20 "testing"
21
22 "github.com/google/go-cmp/cmp"
23 batch "k8s.io/api/batch/v1"
24 "k8s.io/klog/v2/ktesting"
25 "k8s.io/utils/ptr"
26 )
27
28 func TestMatchSuccessPolicy(t *testing.T) {
29 testCases := map[string]struct {
30 successPolicy *batch.SuccessPolicy
31 completions int32
32 succeededIndexes orderedIntervals
33 wantMessage string
34 wantMetSuccessPolicy bool
35 }{
36 "successPolicy is null": {
37 completions: 10,
38 succeededIndexes: orderedIntervals{{0, 0}},
39 },
40 "any rules are nothing": {
41 completions: 10,
42 succeededIndexes: orderedIntervals{{0, 0}},
43 successPolicy: &batch.SuccessPolicy{Rules: []batch.SuccessPolicyRule{}},
44 },
45 "rules.succeededIndexes is invalid format": {
46 completions: 10,
47 succeededIndexes: orderedIntervals{{0, 0}},
48 successPolicy: &batch.SuccessPolicy{
49 Rules: []batch.SuccessPolicyRule{{
50 SucceededIndexes: ptr.To("invalid-form"),
51 }},
52 },
53 },
54 "rules.succeededIndexes is specified; succeededIndexes matched rules": {
55 completions: 10,
56 succeededIndexes: orderedIntervals{{0, 2}, {4, 7}},
57 successPolicy: &batch.SuccessPolicy{
58 Rules: []batch.SuccessPolicyRule{{
59 SucceededIndexes: ptr.To("0-2"),
60 }},
61 },
62 wantMessage: "Matched rules at index 0",
63 wantMetSuccessPolicy: true,
64 },
65 "rules.succeededIndexes is specified; succeededIndexes didn't match rules": {
66 completions: 10,
67 succeededIndexes: orderedIntervals{{0, 2}},
68 successPolicy: &batch.SuccessPolicy{
69 Rules: []batch.SuccessPolicyRule{{
70 SucceededIndexes: ptr.To("3"),
71 }},
72 },
73 },
74 "rules.succeededCount is specified; succeededIndexes matched rules": {
75 completions: 10,
76 succeededIndexes: orderedIntervals{{0, 2}},
77 successPolicy: &batch.SuccessPolicy{
78 Rules: []batch.SuccessPolicyRule{{
79 SucceededCount: ptr.To[int32](2),
80 }},
81 },
82 wantMessage: "Matched rules at index 0",
83 wantMetSuccessPolicy: true,
84 },
85 "rules.succeededCount is specified; succeededIndexes didn't match rules": {
86 completions: 10,
87 succeededIndexes: orderedIntervals{{0, 2}},
88 successPolicy: &batch.SuccessPolicy{
89 Rules: []batch.SuccessPolicyRule{{
90 SucceededCount: ptr.To[int32](4),
91 }},
92 },
93 },
94 "multiple rules; rules.succeededIndexes is specified; succeededIndexes met one of rules": {
95 completions: 10,
96 succeededIndexes: orderedIntervals{{0, 2}, {4, 7}},
97 successPolicy: &batch.SuccessPolicy{
98 Rules: []batch.SuccessPolicyRule{
99 {
100 SucceededIndexes: ptr.To("9"),
101 },
102 {
103 SucceededIndexes: ptr.To("4,6"),
104 },
105 },
106 },
107 wantMessage: "Matched rules at index 1",
108 wantMetSuccessPolicy: true,
109 },
110 "multiple rules; rules.succeededIndexes is specified; succeededIndexes met all rules": {
111 completions: 10,
112 succeededIndexes: orderedIntervals{{0, 2}, {4, 7}},
113 successPolicy: &batch.SuccessPolicy{
114 Rules: []batch.SuccessPolicyRule{
115 {
116 SucceededIndexes: ptr.To("0,1"),
117 },
118 {
119 SucceededIndexes: ptr.To("5"),
120 },
121 },
122 },
123 wantMessage: "Matched rules at index 0",
124 wantMetSuccessPolicy: true,
125 },
126 "rules.succeededIndexes and rules.succeededCount are specified; succeededIndexes met all rules": {
127 completions: 10,
128 succeededIndexes: orderedIntervals{{0, 2}, {4, 7}},
129 successPolicy: &batch.SuccessPolicy{
130 Rules: []batch.SuccessPolicyRule{{
131 SucceededIndexes: ptr.To("3-6"),
132 SucceededCount: ptr.To[int32](2),
133 }},
134 },
135 wantMetSuccessPolicy: true,
136 wantMessage: "Matched rules at index 0",
137 },
138 "rules.succeededIndexes and rules.succeededCount are specified; succeededIndexes didn't match rules": {
139 completions: 10,
140 succeededIndexes: orderedIntervals{{0, 2}, {6, 7}},
141 successPolicy: &batch.SuccessPolicy{
142 Rules: []batch.SuccessPolicyRule{{
143 SucceededIndexes: ptr.To("3-6"),
144 SucceededCount: ptr.To[int32](2),
145 }},
146 },
147 },
148 "rules.succeededIndexes is specified; succeededIndexes are nothing": {
149 completions: 10,
150 succeededIndexes: orderedIntervals{},
151 successPolicy: &batch.SuccessPolicy{
152 Rules: []batch.SuccessPolicyRule{{
153 SucceededCount: ptr.To[int32](4),
154 }},
155 },
156 },
157
158 "rules.succeededIndexes is specified; succeededIndexes matched rules; rules is proper subset of succeededIndexes": {
159 completions: 10,
160 succeededIndexes: orderedIntervals{{1, 5}, {6, 9}},
161 successPolicy: &batch.SuccessPolicy{
162 Rules: []batch.SuccessPolicyRule{{
163 SucceededIndexes: ptr.To("2-4,6-8"),
164 }},
165 },
166 wantMetSuccessPolicy: true,
167 wantMessage: "Matched rules at index 0",
168 },
169 "rules.succeededIndexes is specified; succeededIndexes matched rules; rules equals succeededIndexes": {
170 completions: 10,
171 succeededIndexes: orderedIntervals{{2, 4}, {6, 9}},
172 successPolicy: &batch.SuccessPolicy{
173 Rules: []batch.SuccessPolicyRule{{
174 SucceededIndexes: ptr.To("2-4,6-9"),
175 }},
176 },
177 wantMetSuccessPolicy: true,
178 wantMessage: "Matched rules at index 0",
179 },
180 "rules.succeededIndexes is specified; succeededIndexes matched rules; rules is subset of succeededIndexes": {
181 completions: 10,
182 succeededIndexes: orderedIntervals{{2, 5}, {7, 15}},
183 successPolicy: &batch.SuccessPolicy{
184 Rules: []batch.SuccessPolicyRule{{
185 SucceededIndexes: ptr.To("2-4,8-12"),
186 }},
187 },
188 wantMetSuccessPolicy: true,
189 wantMessage: "Matched rules at index 0",
190 },
191 "rules.succeededIndexes is specified; succeededIndexes didn't match rules; rules is an empty set": {
192 completions: 10,
193 succeededIndexes: orderedIntervals{{1, 3}},
194 successPolicy: &batch.SuccessPolicy{
195 Rules: []batch.SuccessPolicyRule{{
196 SucceededIndexes: ptr.To(""),
197 }},
198 },
199 },
200 "rules.succeededIndexes is specified; succeededIndexes didn't match rules; succeededIndexes is an empty set": {
201 completions: 10,
202 succeededIndexes: orderedIntervals{},
203 successPolicy: &batch.SuccessPolicy{
204 Rules: []batch.SuccessPolicyRule{{
205 SucceededIndexes: ptr.To(""),
206 }},
207 },
208 },
209 "rules.succeededIndexes is specified; succeededIndexes didn't match rules; rules and succeededIndexes are empty set": {
210 completions: 10,
211 succeededIndexes: orderedIntervals{},
212 successPolicy: &batch.SuccessPolicy{
213 Rules: []batch.SuccessPolicyRule{{
214 SucceededIndexes: ptr.To(""),
215 }},
216 },
217 },
218 "rules.succeededIndexes is specified; succeededIndexes didn't match rules; all elements of rules.succeededIndexes aren't included in succeededIndexes": {
219 completions: 10,
220 succeededIndexes: orderedIntervals{{1, 3}, {5, 7}},
221 successPolicy: &batch.SuccessPolicy{
222 Rules: []batch.SuccessPolicyRule{{
223 SucceededIndexes: ptr.To("10-12,14-16"),
224 }},
225 },
226 },
227 "rules.succeededIndexes is specified; succeededIndexes didn't match rules; rules overlaps succeededIndexes at first": {
228 completions: 10,
229 succeededIndexes: orderedIntervals{{2, 4}, {6, 8}},
230 successPolicy: &batch.SuccessPolicy{
231 Rules: []batch.SuccessPolicyRule{{
232 SucceededIndexes: ptr.To("1-3,5-7"),
233 }},
234 },
235 },
236 "rules.succeededIndexes and rules.succeededCount are specified; succeededIndexes matched rules; rules overlaps succeededIndexes at first": {
237 completions: 10,
238 succeededIndexes: orderedIntervals{{2, 4}, {6, 8}},
239 successPolicy: &batch.SuccessPolicy{
240 Rules: []batch.SuccessPolicyRule{{
241 SucceededIndexes: ptr.To("1-3,5-7"),
242 SucceededCount: ptr.To[int32](4),
243 }},
244 },
245 wantMetSuccessPolicy: true,
246 wantMessage: "Matched rules at index 0",
247 },
248 "rules.succeededIndexes is specified; succeededIndexes didn't match rules; rules overlaps succeededIndexes at last": {
249 completions: 10,
250 succeededIndexes: orderedIntervals{{1, 3}, {5, 7}},
251 successPolicy: &batch.SuccessPolicy{
252 Rules: []batch.SuccessPolicyRule{{
253 SucceededIndexes: ptr.To("2-4,6-9"),
254 }},
255 },
256 },
257 "rules.succeededIndexes and rules.succeededCount are specified; succeededIndexes matched rules; rules overlaps succeededIndexes at last": {
258 completions: 10,
259 succeededIndexes: orderedIntervals{{1, 3}, {5, 7}},
260 successPolicy: &batch.SuccessPolicy{
261 Rules: []batch.SuccessPolicyRule{{
262 SucceededIndexes: ptr.To("2-4,6-9"),
263 SucceededCount: ptr.To[int32](4),
264 }},
265 },
266 wantMetSuccessPolicy: true,
267 wantMessage: "Matched rules at index 0",
268 },
269 "rules.succeededIndexes is specified; succeededIndexes didn't match rules; rules completely overlaps succeededIndexes": {
270 completions: 10,
271 succeededIndexes: orderedIntervals{{1, 3}, {7, 8}},
272 successPolicy: &batch.SuccessPolicy{
273 Rules: []batch.SuccessPolicyRule{{
274 SucceededIndexes: ptr.To("0-4,6-9"),
275 }},
276 },
277 },
278 "rules.succeededIndexes and rules.succeededCount are specified; succeededIndexes matched rules; rules completely overlaps succeededIndexes": {
279 completions: 10,
280 succeededIndexes: orderedIntervals{{1, 3}, {7, 8}},
281 successPolicy: &batch.SuccessPolicy{
282 Rules: []batch.SuccessPolicyRule{{
283 SucceededIndexes: ptr.To("0-4,6-9"),
284 SucceededCount: ptr.To[int32](5),
285 }},
286 },
287 wantMetSuccessPolicy: true,
288 wantMessage: "Matched rules at index 0",
289 },
290 "rules.succeededIndexes is specified; succeededIndexes didn't match rules; rules overlaps multiple succeededIndexes at last": {
291 completions: 10,
292 succeededIndexes: orderedIntervals{{1, 3}, {5, 9}},
293 successPolicy: &batch.SuccessPolicy{
294 Rules: []batch.SuccessPolicyRule{{
295 SucceededIndexes: ptr.To("0-6,8-9"),
296 }},
297 },
298 },
299 "rules.succeededIndexes and rules.succeededCount are specified; succeededIndexes matched rules; rules overlaps multiple succeededIndexes at last": {
300 completions: 10,
301 succeededIndexes: orderedIntervals{{1, 3}, {5, 9}},
302 successPolicy: &batch.SuccessPolicy{
303 Rules: []batch.SuccessPolicyRule{{
304 SucceededIndexes: ptr.To("0-6,8-9"),
305 SucceededCount: ptr.To[int32](7),
306 }},
307 },
308 wantMetSuccessPolicy: true,
309 wantMessage: "Matched rules at index 0",
310 },
311 "rules.succeededIndexes is specified; succeededIndexes didn't match rules; rules overlaps succeededIndexes at first, and rules equals succeededIndexes at last": {
312 completions: 10,
313 succeededIndexes: orderedIntervals{{1, 5}, {7, 10}},
314 successPolicy: &batch.SuccessPolicy{
315 Rules: []batch.SuccessPolicyRule{{
316 SucceededIndexes: ptr.To("0-5,7-9"),
317 }},
318 },
319 },
320 "rules.succeededIndexes and rules.succeededCount are specified; succeededIndexes matched rules; rules overlaps succeededIndexes at first, and rules equals succeededIndexes at last": {
321 completions: 10,
322 succeededIndexes: orderedIntervals{{1, 5}, {7, 10}},
323 successPolicy: &batch.SuccessPolicy{
324 Rules: []batch.SuccessPolicyRule{{
325 SucceededIndexes: ptr.To("0-5,7-9"),
326 SucceededCount: ptr.To[int32](8),
327 }},
328 },
329 wantMetSuccessPolicy: true,
330 wantMessage: "Matched rules at index 0",
331 },
332 "rules.succeededIndexes is specified; succeededIndexes didn't match rules; the first rules overlaps succeededIndexes at first": {
333 completions: 10,
334 succeededIndexes: orderedIntervals{{1, 10}},
335 successPolicy: &batch.SuccessPolicy{
336 Rules: []batch.SuccessPolicyRule{{
337 SucceededIndexes: ptr.To("0-3,6-9"),
338 }},
339 },
340 },
341 "rules.succeededIndexes and rules.succeededCount are specified; succeededIndexes matched rules; the first rules overlaps succeededIndexes at first": {
342 completions: 10,
343 succeededIndexes: orderedIntervals{{1, 10}},
344 successPolicy: &batch.SuccessPolicy{
345 Rules: []batch.SuccessPolicyRule{{
346 SucceededIndexes: ptr.To("0-3,6-9"),
347 SucceededCount: ptr.To[int32](7),
348 }},
349 },
350 wantMetSuccessPolicy: true,
351 wantMessage: "Matched rules at index 0",
352 },
353 }
354 for name, tc := range testCases {
355 t.Run(name, func(t *testing.T) {
356 logger := ktesting.NewLogger(t,
357 ktesting.NewConfig(
358 ktesting.BufferLogs(true),
359 ),
360 )
361 gotMessage, gotMetSuccessPolicy := matchSuccessPolicy(logger, tc.successPolicy, tc.completions, tc.succeededIndexes)
362 if tc.wantMetSuccessPolicy != gotMetSuccessPolicy {
363 t.Errorf("Unexpected bool from matchSuccessPolicy\nwant:%v\ngot:%v\n", tc.wantMetSuccessPolicy, gotMetSuccessPolicy)
364 }
365 if diff := cmp.Diff(tc.wantMessage, gotMessage); diff != "" {
366 t.Errorf("Unexpected message from matchSuccessPolicy (-want,+got):\n%s", diff)
367 }
368 })
369 }
370 }
371
View as plain text