Skip to content

Commit

Permalink
Handle conditions in task result subsitution
Browse files Browse the repository at this point in the history
(cherry picked from commit e939852)

Had to remove usage of ConditionRegisterName from apply_test which
hadn't been added in this release branch.
  • Loading branch information
othomann authored and tekton-robot committed Apr 23, 2020
1 parent acfeaad commit 1e6f2fb
Show file tree
Hide file tree
Showing 7 changed files with 283 additions and 8 deletions.
110 changes: 110 additions & 0 deletions examples/v1beta1/pipelineruns/pipeline-result-conditions.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
apiVersion: tekton.dev/v1alpha1
kind: Condition
metadata:
name: condition-1
spec:
check:
args:
- EXITCODE=$(python -c "import sys; input1=str.rstrip(sys.argv[1]); input2=str.rstrip(sys.argv[2]); print(0) if (input1 == 'heads') else
print(1)" '$(params.flip-coin)' 'heads'); exit $EXITCODE
command:
- sh
- -c
image: python:alpine3.6
params:
- name: flip-coin
---
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: flip-coin
spec:
results:
- description: /tmp/output
name: output
steps:
- args:
- python -c "import random; result = 'heads' if random.randint(0,1) == 0 else
'tails'; result='heads'; print(result)" | tee $(results.output.path)
command:
- sh
- -c
image: python:alpine3.6
name: flip-coin
---
apiVersion: tekton.dev/v1alpha1
kind: Task
metadata:
name: condition-check
spec:
params:
- name: flip-coin
results:
- description: /tmp/output
name: output
steps:
- args:
- EXITCODE=$(python -c "import sys; input1=str.rstrip(sys.argv[1]); input2=str.rstrip(sys.argv[2]); print(input1) if (input1 == 'heads') else
print(input1)" '$(params.flip-coin)' 'heads'); echo $EXITCODE | tee $(results.output.path)
command:
- sh
- -c
image: python:alpine3.6
---
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: generate-random-number
spec:
results:
- description: /tmp/output
name: output
steps:
- args:
- python -c "import random; print(random.randint($0, $1))" | tee $2
- '0'
- '9'
- $(results.output.path)
command:
- sh
- -c
image: python:alpine3.6
name: generate-random-number
---
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
annotations:
pipelines.kubeflow.org/pipeline_spec: '{"description": "Shows how to use dsl.Condition().",
"name": "Conditional execution pipeline"}'
name: flip-cond-gen-pipeline
spec:
params: []
tasks:
- name: flip-coin
params: []
taskRef:
name: flip-coin
- name: condition-check
params:
- name: flip-coin
value: $(tasks.flip-coin.results.output)
taskRef:
name: condition-check
- conditions:
- conditionRef: condition-1
params:
- name: flip-coin
value: $(tasks.flip-coin.results.output)
name: generate-random-number
params: []
taskRef:
name: generate-random-number
---
apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
name: flip-cond-gen-pipeline-run
spec:
pipelineRef:
name: flip-cond-gen-pipeline
1 change: 1 addition & 0 deletions pkg/apis/pipeline/v1alpha1/pipeline_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ func (pt PipelineTask) Deps() []string {
}
}
}

return deps
}

Expand Down
46 changes: 46 additions & 0 deletions pkg/reconciler/pipeline/dag/dag_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -669,3 +669,49 @@ func TestBuild_TaskParamsFromTaskResults(t *testing.T) {
}
assertSameDAG(t, expectedDAG, g)
}

func TestBuild_ConditionsParamsFromTaskResults(t *testing.T) {
a := v1alpha1.PipelineTask{Name: "a"}
xDependsOnA := v1alpha1.PipelineTask{
Name: "x",
Conditions: []v1beta1.PipelineTaskCondition{{
ConditionRef: "cond",
Params: []v1alpha1.Param{
{
Name: "paramX",
Value: v1beta1.ArrayOrString{
Type: v1alpha1.ParamTypeString,
StringVal: "$(tasks.a.results.resultA)",
},
},
},
},
},
}

// a
// |
// x
nodeA := &dag.Node{Task: a}
nodeX := &dag.Node{Task: xDependsOnA}

nodeA.Next = []*dag.Node{nodeX}
nodeX.Prev = []*dag.Node{nodeA}
expectedDAG := &dag.Graph{
Nodes: map[string]*dag.Node{
"a": nodeA,
"x": nodeX,
},
}
p := &v1alpha1.Pipeline{
ObjectMeta: metav1.ObjectMeta{Name: "pipeline"},
Spec: v1alpha1.PipelineSpec{
Tasks: []v1alpha1.PipelineTask{a, xDependsOnA},
},
}
g, err := dag.Build(v1alpha1.PipelineTaskList(p.Spec.Tasks))
if err != nil {
t.Fatalf("didn't expect error creating valid Pipeline %v but got %v", p, err)
}
assertSameDAG(t, expectedDAG, g)
}
14 changes: 11 additions & 3 deletions pkg/reconciler/pipelinerun/resources/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,17 @@ func ApplyTaskResults(targets PipelineRunState, resolvedResultRefs ResolvedResul
}

for _, resolvedPipelineRunTask := range targets {
pipelineTask := resolvedPipelineRunTask.PipelineTask.DeepCopy()
pipelineTask.Params = replaceParamValues(pipelineTask.Params, stringReplacements, nil)
resolvedPipelineRunTask.PipelineTask = pipelineTask
// also make substitution for resolved condition checks
for _, resolvedConditionCheck := range resolvedPipelineRunTask.ResolvedConditionChecks {
pipelineTaskCondition := resolvedConditionCheck.PipelineTaskCondition.DeepCopy()
pipelineTaskCondition.Params = replaceParamValues(pipelineTaskCondition.Params, stringReplacements, nil)
resolvedConditionCheck.PipelineTaskCondition = pipelineTaskCondition
}
if resolvedPipelineRunTask.PipelineTask != nil {
pipelineTask := resolvedPipelineRunTask.PipelineTask.DeepCopy()
pipelineTask.Params = replaceParamValues(pipelineTask.Params, stringReplacements, nil)
resolvedPipelineRunTask.PipelineTask = pipelineTask
}
}
}

Expand Down
94 changes: 94 additions & 0 deletions pkg/reconciler/pipelinerun/resources/apply_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import (
"testing"

"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1"
"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1"
Expand Down Expand Up @@ -286,3 +288,95 @@ func TestApplyTaskResults_EmbeddedExpression(t *testing.T) {
})
}
}

func TestApplyTaskResults_Conditions(t *testing.T) {
type args struct {
targets PipelineRunState
resolvedResultRefs ResolvedResultRefs
}
tests := []struct {
name string
args args
want PipelineRunState
}{{
name: "Test result substitution in condition parameter",
args: args{
resolvedResultRefs: ResolvedResultRefs{
{
Value: v1beta1.ArrayOrString{
Type: v1beta1.ParamTypeString,
StringVal: "aResultValue",
},
ResultReference: v1beta1.ResultRef{
PipelineTask: "aTask",
Result: "aResult",
},
FromTaskRun: "aTaskRun",
},
},
targets: PipelineRunState{
{
ResolvedConditionChecks: TaskConditionCheckState{{
ConditionCheckName: "test",
Condition: &v1alpha1.Condition{
ObjectMeta: metav1.ObjectMeta{
Name: "always-true",
},
Spec: v1alpha1.ConditionSpec{
Check: v1alpha1.Step{},
}},
ResolvedResources: map[string]*v1alpha1.PipelineResource{},
PipelineTaskCondition: &v1beta1.PipelineTaskCondition{
Params: []v1beta1.Param{
{
Name: "cParam",
Value: v1beta1.ArrayOrString{
Type: v1beta1.ParamTypeString,
StringVal: "Result value --> $(tasks.aTask.results.aResult)",
},
},
},
},
},
},
},
},
},
want: PipelineRunState{
{
ResolvedConditionChecks: TaskConditionCheckState{{
ConditionCheckName: "test",
Condition: &v1alpha1.Condition{
ObjectMeta: metav1.ObjectMeta{
Name: "always-true",
},
Spec: v1alpha1.ConditionSpec{
Check: v1alpha1.Step{},
}},
ResolvedResources: map[string]*v1alpha1.PipelineResource{},
PipelineTaskCondition: &v1beta1.PipelineTaskCondition{
Params: []v1beta1.Param{
{
Name: "cParam",
Value: v1beta1.ArrayOrString{
Type: v1beta1.ParamTypeString,
StringVal: "Result value --> aResultValue",
},
},
},
},
},
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ApplyTaskResults(tt.args.targets, tt.args.resolvedResultRefs)
if d := cmp.Diff(tt.args.targets[0].ResolvedConditionChecks, tt.want[0].ResolvedConditionChecks, cmpopts.IgnoreUnexported(v1alpha1.TaskRunSpec{}, ResolvedConditionCheck{})); d != "" {
t.Fatalf("ApplyTaskResults() -want, +got: %v", d)
}
})
}
}
23 changes: 21 additions & 2 deletions pkg/reconciler/pipelinerun/resources/resultrefresolution.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,29 @@ func removeDup(refs ResolvedResultRefs) ResolvedResultRefs {
// convertParamsToResultRefs converts all params of the resolved pipeline run task
func convertParamsToResultRefs(pipelineRunState PipelineRunState, target *ResolvedPipelineRunTask) (ResolvedResultRefs, error) {
var resolvedParams ResolvedResultRefs
for _, param := range target.PipelineTask.Params {
for _, condition := range target.PipelineTask.Conditions {
condRefs, err := convertParams(condition.Params, pipelineRunState, condition.ConditionRef)
if err != nil {
return nil, err
}
resolvedParams = append(resolvedParams, condRefs...)
}

taskParamsRefs, err := convertParams(target.PipelineTask.Params, pipelineRunState, target.PipelineTask.Name)
if err != nil {
return nil, err
}
resolvedParams = append(resolvedParams, taskParamsRefs...)

return resolvedParams, nil
}

func convertParams(params []v1beta1.Param, pipelineRunState PipelineRunState, name string) (ResolvedResultRefs, error) {
var resolvedParams ResolvedResultRefs
for _, param := range params {
resolvedResultRefs, err := extractResultRefsForParam(pipelineRunState, param)
if err != nil {
return nil, fmt.Errorf("unable to find result referenced by param %q in pipeline task %q: %w", param.Name, target.PipelineTask.Name, err)
return nil, fmt.Errorf("unable to find result referenced by param %q in %q: %w", param.Name, name, err)
}
if resolvedResultRefs != nil {
resolvedParams = append(resolvedParams, resolvedResultRefs...)
Expand Down
3 changes: 0 additions & 3 deletions pkg/reconciler/taskrun/resources/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,6 @@ func ApplyParameters(spec *v1alpha1.TaskSpec, tr *v1alpha1.TaskRun, defaults ...
arrayReplacements[fmt.Sprintf("inputs.params.%s", p.Name)] = p.Value.ArrayVal
}
}

fmt.Println("stringReplacements", stringReplacements)
fmt.Println("arrayReplacements", arrayReplacements)
return ApplyReplacements(spec, stringReplacements, arrayReplacements)
}

Expand Down

0 comments on commit 1e6f2fb

Please sign in to comment.