Skip to content

Commit

Permalink
fix: Add Step node outputs to global scope (#2826)
Browse files Browse the repository at this point in the history
  • Loading branch information
simster7 committed Apr 24, 2020
1 parent bac339a commit b956ec6
Show file tree
Hide file tree
Showing 4 changed files with 271 additions and 0 deletions.
84 changes: 84 additions & 0 deletions test/e2e/functional/global-scope.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
generateName: overwrite-output-parameter-
labels:
argo-e2e: true
spec:
entrypoint: plan
templates:
- name: plan
steps:

- - name: write-global-parameter
template: global-parameter-generation
arguments:
parameters:
- name: parameter
value: initial

- - name: consume-global-parameter-1
template: global-parameter-consumption

- - name: consume-global-parameter-2
template: global-parameter-consumption

- - name: overwrite-global-parameter
template: nested-global-parameter-generation
arguments:
parameters:
- name: parameter
value: final

- - name: consume-global-parameter-3
template: global-parameter-consumption

- - name: consume-global-parameter-4
template: global-parameter-consumption
outputs:
parameters:
- name: output-1
valueFrom:
parameter: "{{steps.consume-global-parameter-1.outputs.result}}"
- name: output-2
valueFrom:
parameter: "{{steps.consume-global-parameter-2.outputs.result}}"
- name: output-3
valueFrom:
parameter: "{{steps.consume-global-parameter-3.outputs.result}}"
- name: output-4
valueFrom:
parameter: "{{steps.consume-global-parameter-4.outputs.result}}"

- name: global-parameter-generation
inputs:
parameters:
- name: parameter
container:
image: alpine:latest
command: [sh, -c]
args: ["echo '{{inputs.parameters.parameter}}' > /tmp/hello_world.txt"]
outputs:
parameters:
- name: parameter
valueFrom:
path: /tmp/hello_world.txt
globalName: global-parameter

- name: nested-global-parameter-generation
inputs:
parameters:
- name: parameter
steps:
- - name: generate-parameter
template: global-parameter-generation
arguments:
parameters:
- name: parameter
value: "{{inputs.parameters.parameter}}"

- name: global-parameter-consumption
container:
image: alpine:latest
command: [sh, -c]
args: ["echo {{workflow.outputs.parameters.global-parameter}}"]
32 changes: 32 additions & 0 deletions test/e2e/functional_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,38 @@ func (s *FunctionalSuite) TestParameterAggregation() {
})
}

func (s *FunctionalSuite) TestGlobalScope() {
s.Given().
Workflow("@functional/global-scope.yaml").
When().
SubmitWorkflow().
WaitForWorkflow(60 * time.Second).
Then().
ExpectWorkflow(func(t *testing.T, _ *metav1.ObjectMeta, status *wfv1.WorkflowStatus) {
assert.Equal(t, wfv1.NodeSucceeded, status.Phase)
nodeStatus := status.Nodes.FindByDisplayName("consume-global-parameter-1")
if assert.NotNil(t, nodeStatus) {
assert.Equal(t, wfv1.NodeSucceeded, nodeStatus.Phase)
assert.Equal(t, "initial", *nodeStatus.Outputs.Result)
}
nodeStatus = status.Nodes.FindByDisplayName("consume-global-parameter-2")
if assert.NotNil(t, nodeStatus) {
assert.Equal(t, wfv1.NodeSucceeded, nodeStatus.Phase)
assert.Equal(t, "initial", *nodeStatus.Outputs.Result)
}
nodeStatus = status.Nodes.FindByDisplayName("consume-global-parameter-3")
if assert.NotNil(t, nodeStatus) {
assert.Equal(t, wfv1.NodeSucceeded, nodeStatus.Phase)
assert.Equal(t, "final", *nodeStatus.Outputs.Result)
}
nodeStatus = status.Nodes.FindByDisplayName("consume-global-parameter-4")
if assert.NotNil(t, nodeStatus) {
assert.Equal(t, wfv1.NodeSucceeded, nodeStatus.Phase)
assert.Equal(t, "final", *nodeStatus.Outputs.Result)
}
})
}

func (s *FunctionalSuite) TestStopBehavior() {
s.T().SkipNow()
s.Given().
Expand Down
154 changes: 154 additions & 0 deletions workflow/controller/operator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2816,3 +2816,157 @@ func TestContainerOutputsResult(t *testing.T) {
}
}
}

var nestedStepGroupGlobalParams = `
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
name: global-outputs-bg7gl
spec:
arguments: {}
entrypoint: generate-globals
templates:
- arguments: {}
inputs: {}
metadata: {}
name: generate-globals
outputs: {}
steps:
- - arguments: {}
name: generate
template: nested-global-output-generation
- arguments: {}
container:
args:
- sleep 1; echo -n hello world > /tmp/hello_world.txt
command:
- sh
- -c
image: alpine:3.7
name: ""
resources: {}
inputs: {}
metadata: {}
name: output-generation
outputs:
parameters:
- name: hello-param
valueFrom:
path: /tmp/hello_world.txt
- arguments: {}
inputs: {}
metadata: {}
name: nested-global-output-generation
outputs:
parameters:
- globalName: global-param
name: hello-param
valueFrom:
parameter: '{{steps.generate-output.outputs.parameters.hello-param}}'
steps:
- - arguments: {}
name: generate-output
template: output-generation
status:
conditions:
- status: "True"
type: Completed
finishedAt: "2020-04-24T15:55:18Z"
nodes:
global-outputs-bg7gl:
children:
- global-outputs-bg7gl-1831647575
displayName: global-outputs-bg7gl
id: global-outputs-bg7gl
name: global-outputs-bg7gl
outboundNodes:
- global-outputs-bg7gl-1290716463
phase: Running
startedAt: "2020-04-24T15:55:11Z"
templateName: generate-globals
templateScope: local/global-outputs-bg7gl
type: Steps
global-outputs-bg7gl-1290716463:
boundaryID: global-outputs-bg7gl-2228002836
displayName: generate-output
finishedAt: "2020-04-24T15:55:16Z"
hostNodeName: minikube
id: global-outputs-bg7gl-1290716463
name: global-outputs-bg7gl[0].generate[0].generate-output
outputs:
parameters:
- name: hello-param
value: hello world
valueFrom:
path: /tmp/hello_world.txt
phase: Succeeded
startedAt: "2020-04-24T15:55:11Z"
templateName: output-generation
templateScope: local/global-outputs-bg7gl
type: Pod
global-outputs-bg7gl-1831647575:
boundaryID: global-outputs-bg7gl
children:
- global-outputs-bg7gl-2228002836
displayName: '[0]'
finishedAt: "2020-04-24T15:55:18Z"
id: global-outputs-bg7gl-1831647575
name: global-outputs-bg7gl[0]
phase: Succeeded
startedAt: "2020-04-24T15:55:11Z"
templateName: generate-globals
templateScope: local/global-outputs-bg7gl
type: StepGroup
global-outputs-bg7gl-2228002836:
boundaryID: global-outputs-bg7gl
children:
- global-outputs-bg7gl-3089902334
displayName: generate
id: global-outputs-bg7gl-2228002836
name: global-outputs-bg7gl[0].generate
phase: Running
outboundNodes:
- global-outputs-bg7gl-1290716463
startedAt: "2020-04-24T15:55:11Z"
templateName: nested-global-output-generation
templateScope: local/global-outputs-bg7gl
type: Steps
global-outputs-bg7gl-3089902334:
boundaryID: global-outputs-bg7gl-2228002836
children:
- global-outputs-bg7gl-1290716463
displayName: '[0]'
finishedAt: "2020-04-24T15:55:18Z"
id: global-outputs-bg7gl-3089902334
name: global-outputs-bg7gl[0].generate[0]
phase: Succeeded
startedAt: "2020-04-24T15:55:11Z"
templateName: nested-global-output-generation
templateScope: local/global-outputs-bg7gl
type: StepGroup
startedAt: "2020-04-24T15:55:11Z"
`

func TestNestedStepGroupGlobalParams(t *testing.T) {
cancel, controller := newController()
defer cancel()
wfcset := controller.wfclientset.ArgoprojV1alpha1().Workflows("")

// operate the workflow. it should create a pod.
wf := unmarshalWF(nestedStepGroupGlobalParams)
wf, err := wfcset.Create(wf)
assert.NoError(t, err)

woc := newWorkflowOperationCtx(wf, controller)
woc.operate()

node := woc.wf.Status.Nodes.FindByDisplayName("generate")
if assert.NotNil(t, node) {
assert.Equal(t, "hello-param", node.Outputs.Parameters[0].Name)
assert.Equal(t, "global-param", node.Outputs.Parameters[0].GlobalName)
assert.Equal(t, "hello world", *node.Outputs.Parameters[0].Value)
}

assert.Equal(t, "hello world", *woc.wf.Status.Outputs.Parameters[0].Value)
assert.Equal(t, "global-param", woc.wf.Status.Outputs.Parameters[0].Name)
}
1 change: 1 addition & 0 deletions workflow/controller/steps.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ func (woc *wfOperationCtx) executeSteps(nodeName string, tmplCtx *templateresolu
if outputs != nil {
node := woc.getNodeByName(nodeName)
node.Outputs = outputs
woc.addOutputsToGlobalScope(node.Outputs)
woc.wf.Status.Nodes[node.ID] = *node
}
return woc.markNodePhase(nodeName, wfv1.NodeSucceeded), nil
Expand Down

0 comments on commit b956ec6

Please sign in to comment.