@@ -3,10 +3,12 @@ package reconciler
33import (
44 "errors"
55 "fmt"
6+ "strings"
67 "testing"
78
89 "github.com/openshift-pipelines/pipelines-as-code/pkg/apis/pipelinesascode/keys"
910 pacv1alpha1 "github.com/openshift-pipelines/pipelines-as-code/pkg/apis/pipelinesascode/v1alpha1"
11+ "github.com/openshift-pipelines/pipelines-as-code/pkg/kubeinteraction"
1012 "github.com/openshift-pipelines/pipelines-as-code/pkg/params"
1113 "github.com/openshift-pipelines/pipelines-as-code/pkg/params/clients"
1214 "github.com/openshift-pipelines/pipelines-as-code/pkg/params/info"
@@ -17,6 +19,8 @@ import (
1719 zapobserver "go.uber.org/zap/zaptest/observer"
1820 "gotest.tools/v3/assert"
1921 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
22+ "k8s.io/apimachinery/pkg/runtime"
23+ k8stesting "k8s.io/client-go/testing"
2024 rtesting "knative.dev/pkg/reconciler/testing"
2125)
2226
@@ -215,26 +219,21 @@ func TestRecordQueuePromotionFailure(t *testing.T) {
215219 fakelogger := zap .New (observer ).Sugar ()
216220
217221 tests := []struct {
218- name string
219- annotations map [string ]string
220- wantRetries string
221- wantBlocked bool
222- wantBlockedMarker string
222+ name string
223+ annotations map [string ]string
224+ wantRetries string
223225 }{
224226 {
225227 name : "first failure records retry metadata" ,
226228 annotations : map [string ]string {},
227229 wantRetries : "1" ,
228- wantBlocked : false ,
229230 },
230231 {
231- name : "reaching retry limit blocks future promotion" ,
232+ name : "later failures keep incrementing retries without blocking promotion" ,
232233 annotations : map [string ]string {
233234 keys .QueuePromotionRetries : "4" ,
234235 },
235- wantRetries : "5" ,
236- wantBlocked : true ,
237- wantBlockedMarker : "true" ,
236+ wantRetries : "5" ,
238237 },
239238 }
240239
@@ -261,21 +260,92 @@ func TestRecordQueuePromotionFailure(t *testing.T) {
261260 },
262261 }
263262
264- blocked , err := r .recordQueuePromotionFailure (ctx , fakelogger , pipelineRun , errors .New ("cannot patch" ))
263+ err := r .recordQueuePromotionFailure (ctx , fakelogger , pipelineRun , errors .New ("cannot patch" ))
265264 assert .NilError (t , err )
266- assert .Equal (t , blocked , tt .wantBlocked )
267265
268266 updatedPR , err := stdata .Pipeline .TektonV1 ().PipelineRuns ("test" ).Get (ctx , "test-pr" , metav1.GetOptions {})
269267 assert .NilError (t , err )
270268 assert .Equal (t , updatedPR .GetAnnotations ()[keys .QueuePromotionRetries ], tt .wantRetries )
271269 assert .Equal (t , updatedPR .GetAnnotations ()[keys .QueuePromotionLastErr ], "cannot patch" )
272-
273- if tt .wantBlockedMarker == "" {
274- _ , exists := updatedPR .GetAnnotations ()[keys .QueuePromotionBlocked ]
275- assert .Assert (t , ! exists , "QueuePromotionBlocked should not be set before the retry limit is reached" )
276- } else {
277- assert .Equal (t , updatedPR .GetAnnotations ()[keys .QueuePromotionBlocked ], tt .wantBlockedMarker )
278- }
270+ _ , exists := updatedPR .GetAnnotations ()[keys .QueuePromotionBlocked ]
271+ assert .Assert (t , ! exists , "QueuePromotionBlocked should not be set when promotion fails" )
279272 })
280273 }
281274}
275+
276+ func TestQueuePipelineRunStopsAfterSinglePromotionFailure (t * testing.T ) {
277+ observer , _ := zapobserver .New (zap .InfoLevel )
278+ fakelogger := zap .New (observer ).Sugar ()
279+ ctx , _ := rtesting .SetupFakeContext (t )
280+
281+ pipelineRun := & tektonv1.PipelineRun {
282+ ObjectMeta : metav1.ObjectMeta {
283+ Name : "queued" ,
284+ Namespace : "test" ,
285+ Annotations : map [string ]string {
286+ keys .ExecutionOrder : "test/queued" ,
287+ keys .Repository : "test" ,
288+ keys .State : kubeinteraction .StateQueued ,
289+ },
290+ },
291+ Spec : tektonv1.PipelineRunSpec {
292+ Status : tektonv1 .PipelineRunSpecStatusPending ,
293+ },
294+ }
295+ testRepo := & pacv1alpha1.Repository {
296+ ObjectMeta : metav1.ObjectMeta {
297+ Name : "test" ,
298+ Namespace : "test" ,
299+ },
300+ Spec : pacv1alpha1.RepositorySpec {
301+ URL : randomURL ,
302+ },
303+ }
304+
305+ testData := testclient.Data {
306+ Repositories : []* pacv1alpha1.Repository {testRepo },
307+ PipelineRuns : []* tektonv1.PipelineRun {pipelineRun },
308+ }
309+ stdata , informers := testclient .SeedTestData (t , ctx , testData )
310+ patchCalls := 0
311+ stdata .Pipeline .PrependReactor ("patch" , "pipelineruns" , func (_ k8stesting.Action ) (bool , runtime.Object , error ) {
312+ patchCalls ++
313+ if patchCalls == 1 {
314+ return true , nil , errors .New ("boom" )
315+ }
316+ return false , nil , nil
317+ })
318+
319+ r := & Reconciler {
320+ qm : testconcurrency.TestQMI {
321+ RunningQueue : []string {"test/queued" },
322+ },
323+ repoLister : informers .Repository .Lister (),
324+ run : & params.Run {
325+ Info : info.Info {
326+ Kube : & info.KubeOpts {
327+ Namespace : "global" ,
328+ },
329+ Controller : & info.ControllerInfo {},
330+ },
331+ Clients : clients.Clients {
332+ PipelineAsCode : stdata .PipelineAsCode ,
333+ Tekton : stdata .Pipeline ,
334+ Kube : stdata .Kube ,
335+ Log : fakelogger ,
336+ },
337+ },
338+ }
339+
340+ err := r .queuePipelineRun (ctx , fakelogger , pipelineRun )
341+ assert .ErrorContains (t , err , "failed to update pipelineRun to in_progress" )
342+
343+ updatedPR , getErr := stdata .Pipeline .TektonV1 ().PipelineRuns ("test" ).Get (ctx , "queued" , metav1.GetOptions {})
344+ assert .NilError (t , getErr )
345+ assert .Equal (t , updatedPR .GetAnnotations ()[keys .QueuePromotionRetries ], "1" )
346+ assert .Assert (t , updatedPR .GetAnnotations ()[keys .QueuePromotionLastErr ] != "" )
347+ assert .Assert (t , strings .Contains (updatedPR .GetAnnotations ()[keys .QueuePromotionLastErr ], "cannot update state" ))
348+ assert .Assert (t , strings .Contains (updatedPR .GetAnnotations ()[keys .QueuePromotionLastErr ], "boom" ))
349+ _ , exists := updatedPR .GetAnnotations ()[keys .QueuePromotionBlocked ]
350+ assert .Assert (t , ! exists , "QueuePromotionBlocked should not be set when queuePipelineRun returns after a failed promotion" )
351+ }
0 commit comments