@@ -1736,16 +1736,44 @@ spec:
17361736 name: test-pipeline
17371737 serviceAccountName: test-sa
17381738status:
1739+ conditions:
1740+ - message: running...
1741+ reason: Running
1742+ status: Unknown
1743+ type: Succeeded
17391744 startTime: "2021-12-31T00:00:00Z"
1745+ runs:
1746+ test-pipeline-run-custom-task-hello-world-1:
1747+ pipelineTaskName: hello-world-1
1748+ status:
1749+ conditions:
1750+ - status: Unknown
1751+ type: Succeeded
17401752` )}
17411753 prs [0 ].Spec .Timeout = tc .timeout
17421754 prs [0 ].Spec .Timeouts = tc .timeouts
17431755
1756+ runs := []* v1alpha1.Run {mustParseRunWithObjectMeta (t ,
1757+ taskRunObjectMeta ("test-pipeline-run-custom-task-hello-world-1" , "test" , "test-pipeline-run-custom-task" ,
1758+ "test-pipeline" , "hello-world-1" , true ),
1759+ `
1760+ spec:
1761+ ref:
1762+ apiVersion: example.dev/v0
1763+ kind: Example
1764+ status:
1765+ conditions:
1766+ - status: Unknown
1767+ type: Succeeded
1768+ startTime: "2021-12-31T11:58:59Z"
1769+ ` )}
1770+
17441771 cms := []* corev1.ConfigMap {withCustomTasks (newFeatureFlagsConfigMap ())}
17451772 d := test.Data {
17461773 PipelineRuns : prs ,
17471774 Pipelines : ps ,
17481775 ConfigMaps : cms ,
1776+ Runs : runs ,
17491777 }
17501778 prt := newPipelineRunTest (d , t )
17511779 defer prt .Cancel ()
@@ -1763,9 +1791,9 @@ status:
17631791 }
17641792
17651793 gotTimeoutValue := postReconcileRun .GetTimeout ()
1766- expectedTimeoutValue := time .Second
1794+ expectedTimeoutValue := time .Hour
17671795
1768- if d := cmp .Diff (gotTimeoutValue , expectedTimeoutValue ); d != "" {
1796+ if d := cmp .Diff (expectedTimeoutValue , gotTimeoutValue ); d != "" {
17691797 t .Fatalf ("Expected timeout for created Run, but got a mismatch %s" , diff .PrintWantGot (d ))
17701798 }
17711799
@@ -2755,6 +2783,120 @@ spec:
27552783 }
27562784}
27572785
2786+ func TestReconcileFailsTaskRunTimeOut (t * testing.T ) {
2787+ prName := "test-pipeline-fails-to-timeout"
2788+
2789+ // TestReconcileFailsTaskRunTimeOut runs "Reconcile" on a PipelineRun with a single TaskRun.
2790+ // The TaskRun cannot be timed out. Check that the pipelinerun timeout fails, that reconcile fails and
2791+ // an event is generated
2792+ names .TestingSeed ()
2793+ prs := []* v1beta1.PipelineRun {parse .MustParsePipelineRun (t , `
2794+ metadata:
2795+ name: test-pipeline-fails-to-timeout
2796+ namespace: foo
2797+ spec:
2798+ pipelineRef:
2799+ name: test-pipeline
2800+ timeout: 1h0m0s
2801+ status:
2802+ conditions:
2803+ - message: running...
2804+ reason: Running
2805+ status: Unknown
2806+ type: Succeeded
2807+ startTime: "2021-12-31T22:59:00Z"
2808+ taskRuns:
2809+ test-pipeline-fails-to-timeouthello-world-1:
2810+ pipelineTaskName: hello-world-1
2811+ ` )}
2812+ ps := []* v1beta1.Pipeline {parse .MustParsePipeline (t , `
2813+ metadata:
2814+ name: test-pipeline
2815+ namespace: foo
2816+ spec:
2817+ tasks:
2818+ - name: hello-world-1
2819+ taskRef:
2820+ name: hello-world
2821+ - name: hello-world-2
2822+ taskRef:
2823+ name: hello-world
2824+ ` )}
2825+ tasks := []* v1beta1.Task {simpleHelloWorldTask }
2826+ taskRuns := []* v1beta1.TaskRun {
2827+ getTaskRun (
2828+ t ,
2829+ "test-pipeline-fails-to-timeouthello-world-1" ,
2830+ prName ,
2831+ "test-pipeline" ,
2832+ "hello-world" ,
2833+ corev1 .ConditionUnknown ,
2834+ ),
2835+ }
2836+
2837+ cms := []* corev1.ConfigMap {withEnabledAlphaAPIFields (newFeatureFlagsConfigMap ())}
2838+
2839+ d := test.Data {
2840+ PipelineRuns : prs ,
2841+ Pipelines : ps ,
2842+ Tasks : tasks ,
2843+ TaskRuns : taskRuns ,
2844+ ConfigMaps : cms ,
2845+ }
2846+
2847+ testAssets , cancel := getPipelineRunController (t , d )
2848+ defer cancel ()
2849+ c := testAssets .Controller
2850+ clients := testAssets .Clients
2851+ failingReactorActivated := true
2852+
2853+ // Make the patch call fail, i.e. make it so that the controller fails to cancel the TaskRun
2854+ clients .Pipeline .PrependReactor ("patch" , "taskruns" , func (action ktesting.Action ) (bool , runtime.Object , error ) {
2855+ return failingReactorActivated , nil , fmt .Errorf ("i'm sorry Dave, i'm afraid i can't do that" )
2856+ })
2857+
2858+ err := c .Reconciler .Reconcile (testAssets .Ctx , "foo/test-pipeline-fails-to-timeout" )
2859+ if err == nil {
2860+ t .Errorf ("Expected to see error returned from reconcile after failing to timeout TaskRun but saw none!" )
2861+ }
2862+
2863+ // Check that the PipelineRun is still running with correct error message
2864+ reconciledRun , err := clients .Pipeline .TektonV1beta1 ().PipelineRuns ("foo" ).Get (testAssets .Ctx , "test-pipeline-fails-to-timeout" , metav1.GetOptions {})
2865+ if err != nil {
2866+ t .Fatalf ("Somehow had error getting reconciled run out of fake client: %s" , err )
2867+ }
2868+
2869+ if val , ok := reconciledRun .GetLabels ()[pipeline .PipelineLabelKey ]; ! ok {
2870+ t .Fatalf ("expected pipeline label" )
2871+ } else if d := cmp .Diff ("test-pipeline" , val ); d != "" {
2872+ t .Errorf ("expected to see pipeline label. Diff %s" , diff .PrintWantGot (d ))
2873+ }
2874+
2875+ // The PipelineRun should not be timed out b/c we couldn't timeout the TaskRun
2876+ checkPipelineRunConditionStatusAndReason (t , reconciledRun , corev1 .ConditionUnknown , ReasonCouldntTimeOut )
2877+ // The event here is "Normal" because in case we fail to timeout we leave the condition to unknown
2878+ // Further reconcile might converge then the status of the pipeline.
2879+ // See https://github.com/tektoncd/pipeline/issues/2647 for further details.
2880+ wantEvents := []string {
2881+ "Normal PipelineRunCouldntTimeOut PipelineRun \" test-pipeline-fails-to-timeout\" was timed out but had errors trying to time out TaskRuns and/or Runs" ,
2882+ "Warning InternalError 1 error occurred" ,
2883+ }
2884+ err = eventstest .CheckEventsOrdered (t , testAssets .Recorder .Events , prName , wantEvents )
2885+ if err != nil {
2886+ t .Errorf (err .Error ())
2887+ }
2888+
2889+ // Turn off failing reactor and retry reconciliation
2890+ failingReactorActivated = false
2891+
2892+ err = c .Reconciler .Reconcile (testAssets .Ctx , "foo/test-pipeline-fails-to-timeout" )
2893+ if err == nil {
2894+ // No error is ok
2895+ } else if ok , _ := controller .IsRequeueKey (err ); ! ok { // Requeue is also fine.
2896+ t .Errorf ("Expected to timeout TaskRun successfully!" )
2897+ }
2898+ }
2899+
27582900func TestReconcilePropagateLabelsAndAnnotations (t * testing.T ) {
27592901 names .TestingSeed ()
27602902
@@ -3094,7 +3236,7 @@ status:
30943236 reconciledRun , _ := prt .reconcileRun ("foo" , "test-pipeline-retry-run-with-timeout" , []string {}, false )
30953237
30963238 if len (reconciledRun .Status .TaskRuns ["hello-world-1" ].Status .RetriesStatus ) != tc .retries {
3097- t .Fatalf (" %d retry expected but %d " , tc .retries , len (reconciledRun .Status .TaskRuns ["hello-world-1" ].Status .RetriesStatus ))
3239+ t .Fatalf (" %d retries expected but got %d " , tc .retries , len (reconciledRun .Status .TaskRuns ["hello-world-1" ].Status .RetriesStatus ))
30983240 }
30993241
31003242 if status := reconciledRun .Status .TaskRuns ["hello-world-1" ].Status .GetCondition (apis .ConditionSucceeded ).Status ; status != tc .conditionSucceeded {
@@ -3240,7 +3382,7 @@ func TestGetTaskRunTimeout(t *testing.T) {
32403382 },
32413383 },
32423384 },
3243- expected : & metav1.Duration {Duration : 10 * time .Minute },
3385+ expected : & metav1.Duration {Duration : 20 * time .Minute },
32443386 }, {
32453387 name : "taskrun with elapsed time; task.timeout applies" ,
32463388 timeoutFields : & v1beta1.TimeoutFields {
@@ -3259,7 +3401,7 @@ func TestGetTaskRunTimeout(t *testing.T) {
32593401 },
32603402 },
32613403 },
3262- expected : & metav1.Duration {Duration : 10 * time .Minute },
3404+ expected : & metav1.Duration {Duration : 15 * time .Minute },
32633405 }, {
32643406 name : "taskrun with elapsed time; timeouts.pipeline applies" ,
32653407 timeoutFields : & v1beta1.TimeoutFields {
@@ -3278,7 +3420,7 @@ func TestGetTaskRunTimeout(t *testing.T) {
32783420 },
32793421 },
32803422 },
3281- expected : & metav1.Duration {Duration : 10 * time .Minute },
3423+ expected : & metav1.Duration {Duration : 15 * time .Minute },
32823424 }}
32833425
32843426 for _ , tc := range tcs {
@@ -3296,7 +3438,7 @@ func TestGetTaskRunTimeout(t *testing.T) {
32963438 },
32973439 },
32983440 }
3299- if d := cmp .Diff (getTaskRunTimeout (context .TODO (), pr , tc .rpt , testClock ), tc . expected ); d != "" {
3441+ if d := cmp .Diff (tc . expected , getTaskRunTimeout (context .TODO (), pr , tc .rpt , testClock )); d != "" {
33003442 t .Errorf ("Unexpected task run timeout. Diff %s" , diff .PrintWantGot (d ))
33013443 }
33023444 })
@@ -3449,7 +3591,7 @@ func TestGetFinallyTaskRunTimeout(t *testing.T) {
34493591 },
34503592 },
34513593 },
3452- expected : & metav1.Duration {Duration : 11 * time .Minute },
3594+ expected : & metav1.Duration {Duration : 15 * time .Minute },
34533595 }}
34543596
34553597 for _ , tc := range tcs {
0 commit comments