@@ -9,37 +9,151 @@ import (
9
9
tektonv1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1"
10
10
"gotest.tools/v3/assert"
11
11
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
12
+ "knative.dev/pkg/apis"
13
+ duckv1 "knative.dev/pkg/apis/duck/v1"
12
14
)
13
15
14
16
func TestPipelineRunSortByCompletionTime (t * testing.T ) {
15
17
clock := clockwork .NewFakeClock ()
16
18
ns := "namespace"
17
19
labels := map [string ]string {}
18
20
success := tektonv1 .PipelineRunReasonSuccessful .String ()
21
+
22
+ pruns := []tektonv1.PipelineRun {
23
+ * (tektontest .MakePRCompletion (clock , "troisieme" , ns , success , nil , labels , 30 )),
24
+ * (tektontest .MakePRCompletion (clock , "premier" , ns , success , nil , labels , 10 )),
25
+ * (tektontest .MakePRCompletion (clock , "second" , ns , success , nil , labels , 20 )),
26
+ }
27
+
28
+ noCompletionTimePR := tektonv1.PipelineRun {
29
+ ObjectMeta : metav1.ObjectMeta {
30
+ Name : "no-completion-time" ,
31
+ Namespace : ns ,
32
+ Labels : labels ,
33
+ },
34
+ Status : tektonv1.PipelineRunStatus {
35
+ Status : duckv1.Status {
36
+ Conditions : duckv1.Conditions {
37
+ {
38
+ Type : apis .ConditionSucceeded ,
39
+ Status : "True" ,
40
+ Reason : success ,
41
+ },
42
+ },
43
+ },
44
+ },
45
+ }
46
+
47
+ prunsMissing := []tektonv1.PipelineRun {
48
+ * (tektontest .MakePRCompletion (clock , "troisieme" , ns , success , nil , labels , 30 )),
49
+ * (tektontest .MakePRCompletion (clock , "premier" , ns , success , nil , labels , 10 )),
50
+ noCompletionTimePR ,
51
+ }
52
+
53
+ prunsWithOneMissing := []tektonv1.PipelineRun {
54
+ * (tektontest .MakePRCompletion (clock , "premier" , ns , success , nil , labels , 10 )),
55
+ noCompletionTimePR ,
56
+ }
57
+
58
+ prunsWithUncompletedFirst := []tektonv1.PipelineRun {
59
+ noCompletionTimePR ,
60
+ * (tektontest .MakePRCompletion (clock , "premier" , ns , success , nil , labels , 10 )),
61
+ }
62
+
19
63
tests := []struct {
20
64
name string
21
65
pruns []tektonv1.PipelineRun
22
66
wantName []string
23
67
}{
24
68
{
25
- pruns : []tektonv1.PipelineRun {
26
- * (tektontest .MakePRCompletion (clock , "troisieme" , ns , success , nil , labels , 30 )),
27
- * (tektontest .MakePRCompletion (clock , "premier" , ns , success , nil , labels , 10 )),
28
- * (tektontest .MakePRCompletion (clock , "second" , ns , success , nil , labels , 20 )),
29
- },
69
+ name : "sort by completion time" ,
70
+ pruns : pruns ,
30
71
wantName : []string {"premier" , "second" , "troisieme" },
31
72
},
32
- // TODO: Add test cases.
73
+ {
74
+ name : "sort by completion time with missing" ,
75
+ pruns : prunsMissing ,
76
+ wantName : []string {"no-completion-time" , "premier" , "troisieme" },
77
+ },
78
+ {
79
+ name : "sort by completion time with one missing" ,
80
+ pruns : prunsWithOneMissing ,
81
+ wantName : []string {"no-completion-time" , "premier" },
82
+ },
83
+ {
84
+ name : "sort with uncompleted item first" ,
85
+ pruns : prunsWithUncompletedFirst ,
86
+ wantName : []string {"no-completion-time" , "premier" },
87
+ },
88
+ {
89
+ name : "empty list" ,
90
+ pruns : []tektonv1.PipelineRun {},
91
+ wantName : []string {},
92
+ },
93
+ {
94
+ name : "single item" ,
95
+ pruns : []tektonv1.PipelineRun {* (tektontest .MakePRCompletion (clock , "premier" , ns , success , nil , labels , 10 ))},
96
+ wantName : []string {"premier" },
97
+ },
33
98
}
34
99
for _ , tt := range tests {
35
100
t .Run (tt .name , func (t * testing.T ) {
36
- for key , value := range PipelineRunSortByCompletionTime (tt .pruns ) {
37
- assert .Equal (t , tt .wantName [key ], value .GetName ())
101
+ got := PipelineRunSortByCompletionTime (tt .pruns )
102
+ gotNames := make ([]string , len (got ))
103
+ for i , pr := range got {
104
+ gotNames [i ] = pr .GetName ()
38
105
}
106
+ assert .DeepEqual (t , tt .wantName , gotNames )
39
107
})
40
108
}
41
109
}
42
110
111
+ func TestPipelineRunSortByCompletionTimeSameTime (t * testing.T ) {
112
+ clock := clockwork .NewFakeClock ()
113
+ ns := "namespace"
114
+ labels := map [string ]string {}
115
+ success := tektonv1 .PipelineRunReasonSuccessful .String ()
116
+
117
+ pruns := []tektonv1.PipelineRun {
118
+ * (tektontest .MakePRCompletion (clock , "first-same-time" , ns , success , nil , labels , 15 )),
119
+ * (tektontest .MakePRCompletion (clock , "second-same-time" , ns , success , nil , labels , 15 )),
120
+ * (tektontest .MakePRCompletion (clock , "third-same-time" , ns , success , nil , labels , 15 )),
121
+ * (tektontest .MakePRCompletion (clock , "earlier" , ns , success , nil , labels , 10 )),
122
+ * (tektontest .MakePRCompletion (clock , "later" , ns , success , nil , labels , 20 )),
123
+ }
124
+
125
+ got := PipelineRunSortByCompletionTime (pruns )
126
+ gotNames := make ([]string , len (got ))
127
+ for i , pr := range got {
128
+ gotNames [i ] = pr .GetName ()
129
+ }
130
+
131
+ // Verify that "earlier" comes first
132
+ assert .Equal (t , "earlier" , gotNames [0 ])
133
+ // Verify that "later" comes last
134
+ assert .Equal (t , "later" , gotNames [len (gotNames )- 1 ])
135
+ // Verify that the three items with same time are in positions 1-3 (any order)
136
+ sameTimeNames := gotNames [1 :4 ]
137
+ expectedSameTime := map [string ]bool {
138
+ "first-same-time" : false ,
139
+ "second-same-time" : false ,
140
+ "third-same-time" : false ,
141
+ }
142
+ for _ , name := range sameTimeNames {
143
+ if _ , exists := expectedSameTime [name ]; exists {
144
+ expectedSameTime [name ] = true
145
+ } else {
146
+ t .Errorf ("Unexpected name %s in same-time group" , name )
147
+ }
148
+ }
149
+ // Verify all expected names were found
150
+ for name , found := range expectedSameTime {
151
+ if ! found {
152
+ t .Errorf ("Expected name %s not found in same-time group" , name )
153
+ }
154
+ }
155
+ }
156
+
43
157
func TestPipelineRunSortByStartTime (t * testing.T ) {
44
158
clock := clockwork .NewFakeClock ()
45
159
ns := "namespace"
@@ -53,8 +167,18 @@ func TestPipelineRunSortByStartTime(t *testing.T) {
53
167
noCompletionPR .Status .CompletionTime = nil
54
168
55
169
notStartedYet := tektontest .MakePRCompletion (clock , "notStarted" , ns , success , nil , labels , 5 )
56
- noCompletionPR .Status .StartTime = nil
57
- noCompletionPR .Status .CompletionTime = nil
170
+ notStartedYet .Status .StartTime = nil
171
+ notStartedYet .Status .CompletionTime = nil
172
+
173
+ prunsWithOneNotStarted := []tektonv1.PipelineRun {
174
+ * (tektontest .MakePRCompletion (clock , "otherFirst" , ns , success , nil , labels , 30 )),
175
+ * notStartedYet ,
176
+ }
177
+
178
+ prunsWithNotStartedFirst := []tektonv1.PipelineRun {
179
+ * notStartedYet ,
180
+ * (tektontest .MakePRCompletion (clock , "otherFirst" , ns , success , nil , labels , 30 )),
181
+ }
58
182
59
183
tests := []struct {
60
184
name string
@@ -83,19 +207,101 @@ func TestPipelineRunSortByStartTime(t *testing.T) {
83
207
{
84
208
name : "not started yet" ,
85
209
pruns : []tektonv1.PipelineRun {
86
- * notStartedYet ,
87
210
* (tektontest .MakePRCompletion (clock , "otherFirst" , ns , success , nil , labels , 30 )),
88
211
* (tektontest .MakePRCompletion (clock , "otherSecond" , ns , success , nil , labels , 10 )),
212
+ * notStartedYet ,
89
213
},
90
- wantName : []string {"otherFirst" , "otherSecond" , "notStarted" },
214
+ wantName : []string {"notStarted" , "otherFirst" , "otherSecond" },
215
+ },
216
+ {
217
+ name : "not started yet single" ,
218
+ pruns : prunsWithOneNotStarted ,
219
+ wantName : []string {"notStarted" , "otherFirst" },
220
+ },
221
+ {
222
+ name : "sort with not-started item first" ,
223
+ pruns : prunsWithNotStartedFirst ,
224
+ wantName : []string {"notStarted" , "otherFirst" },
225
+ },
226
+ {
227
+ name : "empty list" ,
228
+ pruns : []tektonv1.PipelineRun {},
229
+ wantName : []string {},
230
+ },
231
+ {
232
+ name : "single item" ,
233
+ pruns : []tektonv1.PipelineRun {* startedEarlierPR },
234
+ wantName : []string {"earlier" },
91
235
},
92
236
}
93
237
for _ , tt := range tests {
94
238
t .Run (tt .name , func (t * testing.T ) {
95
239
PipelineRunSortByStartTime (tt .pruns )
96
- for key , value := range tt .pruns {
97
- assert .Equal (t , tt .wantName [key ], value .GetName ())
240
+ gotNames := make ([]string , len (tt .pruns ))
241
+ for i , pr := range tt .pruns {
242
+ gotNames [i ] = pr .GetName ()
98
243
}
244
+ assert .DeepEqual (t , tt .wantName , gotNames )
99
245
})
100
246
}
101
247
}
248
+
249
+ func TestPipelineRunSortByStartTimeSameTime (t * testing.T ) {
250
+ clock := clockwork .NewFakeClock ()
251
+ ns := "namespace"
252
+ labels := map [string ]string {}
253
+ success := tektonv1 .PipelineRunReasonSuccessful .String ()
254
+
255
+ sameStartTime := clock .Now ().Add (200 * time .Minute )
256
+
257
+ pr1 := tektontest .MakePRCompletion (clock , "first-same-start" , ns , success , nil , labels , 5 )
258
+ pr1 .Status .StartTime = & metav1.Time {Time : sameStartTime }
259
+ pr1 .Status .CompletionTime = & metav1.Time {Time : sameStartTime .Add (10 * time .Minute )}
260
+
261
+ pr2 := tektontest .MakePRCompletion (clock , "second-same-start" , ns , success , nil , labels , 5 )
262
+ pr2 .Status .StartTime = & metav1.Time {Time : sameStartTime }
263
+ pr2 .Status .CompletionTime = & metav1.Time {Time : sameStartTime .Add (15 * time .Minute )}
264
+
265
+ pr3 := tektontest .MakePRCompletion (clock , "third-same-start" , ns , success , nil , labels , 5 )
266
+ pr3 .Status .StartTime = & metav1.Time {Time : sameStartTime }
267
+ pr3 .Status .CompletionTime = & metav1.Time {Time : sameStartTime .Add (20 * time .Minute )}
268
+
269
+ earlierPR := tektontest .MakePRCompletion (clock , "started-earlier" , ns , success , nil , labels , 5 )
270
+ earlierPR .Status .StartTime = & metav1.Time {Time : sameStartTime .Add (- 60 * time .Minute )}
271
+
272
+ laterPR := tektontest .MakePRCompletion (clock , "started-later" , ns , success , nil , labels , 5 )
273
+ laterPR .Status .StartTime = & metav1.Time {Time : sameStartTime .Add (60 * time .Minute )}
274
+
275
+ pruns := []tektonv1.PipelineRun {* pr1 , * pr2 , * pr3 , * earlierPR , * laterPR }
276
+
277
+ PipelineRunSortByStartTime (pruns )
278
+ gotNames := make ([]string , len (pruns ))
279
+ for i , pr := range pruns {
280
+ gotNames [i ] = pr .GetName ()
281
+ }
282
+
283
+ // Verify that "started-later" comes first (since the sort puts later times first)
284
+ assert .Equal (t , "started-later" , gotNames [0 ])
285
+ // Verify that "started-earlier" comes last
286
+ assert .Equal (t , "started-earlier" , gotNames [len (gotNames )- 1 ])
287
+ // Verify that the three items with same start time are in positions 1-3 (any order)
288
+ sameTimeNames := gotNames [1 :4 ]
289
+ expectedSameTime := map [string ]bool {
290
+ "first-same-start" : false ,
291
+ "second-same-start" : false ,
292
+ "third-same-start" : false ,
293
+ }
294
+ for _ , name := range sameTimeNames {
295
+ if _ , exists := expectedSameTime [name ]; exists {
296
+ expectedSameTime [name ] = true
297
+ } else {
298
+ t .Errorf ("Unexpected name %s in same-start-time group" , name )
299
+ }
300
+ }
301
+ // Verify all expected names were found
302
+ for name , found := range expectedSameTime {
303
+ if ! found {
304
+ t .Errorf ("Expected name %s not found in same-start-time group" , name )
305
+ }
306
+ }
307
+ }
0 commit comments