@@ -22,6 +22,7 @@ import (
22
22
"time"
23
23
24
24
"github.com/google/go-cmp/cmp"
25
+ "github.com/google/go-cmp/cmp/cmpopts"
25
26
"github.com/tektoncd/pipeline/pkg/apis/config"
26
27
cfgtesting "github.com/tektoncd/pipeline/pkg/apis/config/testing"
27
28
"github.com/tektoncd/pipeline/pkg/apis/pipeline/pod"
@@ -31,6 +32,7 @@ import (
31
32
corev1resources "k8s.io/apimachinery/pkg/api/resource"
32
33
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
33
34
"knative.dev/pkg/apis"
35
+ duckv1 "knative.dev/pkg/apis/duck/v1"
34
36
)
35
37
36
38
func TestTaskRun_Invalidate (t * testing.T ) {
@@ -968,3 +970,148 @@ func TestTaskRunSpec_Validate(t *testing.T) {
968
970
})
969
971
}
970
972
}
973
+
974
+ func TestTaskRunSpec_ValidateUpdate (t * testing.T ) {
975
+ tests := []struct {
976
+ name string
977
+ isCreate bool
978
+ isUpdate bool
979
+ baselineTaskRun * v1.TaskRun
980
+ taskRun * v1.TaskRun
981
+ expectedError apis.FieldError
982
+ }{
983
+ {
984
+ name : "is create ctx" ,
985
+ taskRun : & v1.TaskRun {
986
+ Spec : v1.TaskRunSpec {},
987
+ },
988
+ isCreate : true ,
989
+ isUpdate : false ,
990
+ expectedError : apis.FieldError {},
991
+ }, {
992
+ name : "is update ctx, no changes" ,
993
+ baselineTaskRun : & v1.TaskRun {
994
+ Spec : v1.TaskRunSpec {
995
+ Status : "TaskRunCancelled" ,
996
+ },
997
+ },
998
+ taskRun : & v1.TaskRun {
999
+ Spec : v1.TaskRunSpec {
1000
+ Status : "TaskRunCancelled" ,
1001
+ },
1002
+ },
1003
+ isCreate : false ,
1004
+ isUpdate : true ,
1005
+ expectedError : apis.FieldError {},
1006
+ }, {
1007
+ name : "is update ctx, baseline is nil, skip validation" ,
1008
+ baselineTaskRun : nil ,
1009
+ taskRun : & v1.TaskRun {
1010
+ Spec : v1.TaskRunSpec {
1011
+ Timeout : & metav1.Duration {Duration : 1 },
1012
+ },
1013
+ },
1014
+ isCreate : false ,
1015
+ isUpdate : true ,
1016
+ expectedError : apis.FieldError {},
1017
+ }, {
1018
+ name : "is update ctx, baseline is unknown, only status changes" ,
1019
+ baselineTaskRun : & v1.TaskRun {
1020
+ Spec : v1.TaskRunSpec {
1021
+ Status : "" ,
1022
+ StatusMessage : "" ,
1023
+ },
1024
+ Status : v1.TaskRunStatus {
1025
+ Status : duckv1.Status {
1026
+ Conditions : duckv1.Conditions {
1027
+ {Type : apis .ConditionSucceeded , Status : corev1 .ConditionUnknown },
1028
+ },
1029
+ },
1030
+ },
1031
+ },
1032
+ taskRun : & v1.TaskRun {
1033
+ Spec : v1.TaskRunSpec {
1034
+ Status : "TaskRunCancelled" ,
1035
+ StatusMessage : "TaskRun is cancelled" ,
1036
+ },
1037
+ },
1038
+ isCreate : false ,
1039
+ isUpdate : true ,
1040
+ expectedError : apis.FieldError {},
1041
+ }, {
1042
+ name : "is update ctx, baseline is unknown, status and timeout changes" ,
1043
+ baselineTaskRun : & v1.TaskRun {
1044
+ Spec : v1.TaskRunSpec {
1045
+ Status : "" ,
1046
+ StatusMessage : "" ,
1047
+ Timeout : & metav1.Duration {Duration : 0 },
1048
+ },
1049
+ Status : v1.TaskRunStatus {
1050
+ Status : duckv1.Status {
1051
+ Conditions : duckv1.Conditions {
1052
+ {Type : apis .ConditionSucceeded , Status : corev1 .ConditionUnknown },
1053
+ },
1054
+ },
1055
+ },
1056
+ },
1057
+ taskRun : & v1.TaskRun {
1058
+ Spec : v1.TaskRunSpec {
1059
+ Status : "TaskRunCancelled" ,
1060
+ StatusMessage : "TaskRun is cancelled" ,
1061
+ Timeout : & metav1.Duration {Duration : 1 },
1062
+ },
1063
+ },
1064
+ isCreate : false ,
1065
+ isUpdate : true ,
1066
+ expectedError : apis.FieldError {
1067
+ Message : `invalid value: Once the TaskRun has started, only status and statusMessage updates are allowed` ,
1068
+ Paths : []string {"" },
1069
+ },
1070
+ }, {
1071
+ name : "is update ctx, baseline is done, status changes" ,
1072
+ baselineTaskRun : & v1.TaskRun {
1073
+ Spec : v1.TaskRunSpec {
1074
+ Status : "" ,
1075
+ },
1076
+ Status : v1.TaskRunStatus {
1077
+ Status : duckv1.Status {
1078
+ Conditions : duckv1.Conditions {
1079
+ {Type : apis .ConditionSucceeded , Status : corev1 .ConditionTrue },
1080
+ },
1081
+ },
1082
+ },
1083
+ },
1084
+ taskRun : & v1.TaskRun {
1085
+ Spec : v1.TaskRunSpec {
1086
+ Status : "TaskRunCancelled" ,
1087
+ },
1088
+ },
1089
+ isCreate : false ,
1090
+ isUpdate : true ,
1091
+ expectedError : apis.FieldError {
1092
+ Message : `invalid value: Once the TaskRun is complete, no updates are allowed` ,
1093
+ Paths : []string {"" },
1094
+ },
1095
+ },
1096
+ }
1097
+
1098
+ for _ , tt := range tests {
1099
+ t .Run (tt .name , func (t * testing.T ) {
1100
+ ctx := config .ToContext (context .Background (), & config.Config {
1101
+ FeatureFlags : & config.FeatureFlags {},
1102
+ Defaults : & config.Defaults {},
1103
+ })
1104
+ if tt .isCreate {
1105
+ ctx = apis .WithinCreate (ctx )
1106
+ }
1107
+ if tt .isUpdate {
1108
+ ctx = apis .WithinUpdate (ctx , tt .baselineTaskRun )
1109
+ }
1110
+ tr := tt .taskRun
1111
+ err := tr .Spec .ValidateUpdate (ctx )
1112
+ if d := cmp .Diff (tt .expectedError .Error (), err .Error (), cmpopts .IgnoreUnexported (apis.FieldError {})); d != "" {
1113
+ t .Errorf ("TaskRunSpec.ValidateUpdate() errors diff %s" , diff .PrintWantGot (d ))
1114
+ }
1115
+ })
1116
+ }
1117
+ }
0 commit comments