Skip to content

Commit

Permalink
Converts ResultType in PipelineResourceResult string to int
Browse files Browse the repository at this point in the history
This converts the ResultType in PipelineResourceResult from string
to int enum to curtail the size of json object emittted by steps.
ResultTypes were removed because they made JSON messages bigger, which in
turn limited the amount of space in termination messages for task results. String
support is maintained for backwards compatibility.

Closes tektoncd#4150

Signed-off-by: Shivam Mukhade <[email protected]>
  • Loading branch information
Shivam Mukhade committed Aug 29, 2021
1 parent 8e10069 commit d21e087
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 18 deletions.
4 changes: 2 additions & 2 deletions pkg/apis/pipeline/v1beta1/openapi_generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

43 changes: 42 additions & 1 deletion pkg/apis/pipeline/v1beta1/resource_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ limitations under the License.
package v1beta1

import (
"encoding/json"
"fmt"

"github.com/google/go-cmp/cmp"
"github.com/hashicorp/go-multierror"
resource "github.com/tektoncd/pipeline/pkg/apis/resource/v1alpha1"
v1 "k8s.io/api/core/v1"
)
Expand Down Expand Up @@ -130,7 +132,46 @@ type PipelineResourceResult struct {
}

// ResultType used to find out whether a PipelineResourceResult is from a task result or not
type ResultType string
type ResultType int

// UnmarshalJSON unmarshals either an int or a string into a ResultType. String
// ResultTypes were removed because they made JSON messages bigger, which in
// turn limited the amount of space in termination messages for task results. String
// support is maintained for backwards compatibility - the Pipelines controller could
// be stopped midway through TaskRun execution, updated with support for int in place
// of string, and then fail the running TaskRun because it doesn't know how to interpret
// the string value that the TaskRun's entrypoint will emit when it completes.
func (r *ResultType) UnmarshalJSON(data []byte) error {

var asInt int
var intErr error

if err := json.Unmarshal(data, &asInt); err != nil {
intErr = err
} else {
*r = ResultType(asInt)
return nil
}

var asString string

if err := json.Unmarshal(data, &asString); err != nil {
return fmt.Errorf("unsupported value type, neither int nor string: %v", multierror.Append(intErr, err).ErrorOrNil())
}

switch asString {
case "TaskRunResult":
*r = TaskRunResultType
case "PipelineResourceResult":
*r = PipelineResourceResultType
case "InternalTektonResult":
*r = InternalTektonResultType
default:
*r = UnknownResultType
}

return nil
}

// PipelineResourceRef can be used to refer to a specific instance of a Resource
type PipelineResourceRef struct {
Expand Down
35 changes: 35 additions & 0 deletions pkg/apis/pipeline/v1beta1/resource_types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ limitations under the License.
package v1beta1_test

import (
"encoding/json"
"testing"

"github.com/google/go-cmp/cmp"
Expand Down Expand Up @@ -143,3 +144,37 @@ func TestApplyTaskModifier_AlreadyAdded(t *testing.T) {
})
}
}

func TestPipelineResourceResult_UnmarshalJSON(t *testing.T) {

testcases := []struct {
name string
data string
pr v1beta1.PipelineResourceResult
}{{
name: "type defined as string - TaskRunResult",
data: "{\"key\":\"resultName\",\"value\":\"resultValue\", \"type\": \"TaskRunResult\"}",
pr: v1beta1.PipelineResourceResult{Key: "resultName", Value: "resultValue", ResultType: v1beta1.TaskRunResultType},
},
{
name: "type defined as string - InternalTektonResult",
data: "{\"key\":\"resultName\",\"value\":\"\", \"type\": \"InternalTektonResult\"}",
pr: v1beta1.PipelineResourceResult{Key: "resultName", Value: "", ResultType: v1beta1.InternalTektonResultType},
}, {
name: "type defined as int",
data: "{\"key\":\"resultName\",\"value\":\"\", \"type\": 1}",
pr: v1beta1.PipelineResourceResult{Key: "resultName", Value: "", ResultType: v1beta1.TaskRunResultType},
}}

for _, tc := range testcases {
t.Run(tc.name, func(t *testing.T) {
pipRes := v1beta1.PipelineResourceResult{}
if err := json.Unmarshal([]byte(tc.data), &pipRes); err != nil {
t.Errorf("Unexpected error when unmarshalling the json into PipelineResourceResult")
}
if d := cmp.Diff(tc.pr, pipRes); d != "" {
t.Errorf(diff.PrintWantGot(d))
}
})
}
}
3 changes: 2 additions & 1 deletion pkg/apis/pipeline/v1beta1/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -803,7 +803,8 @@
"$ref": "#/definitions/v1beta1.PipelineResourceRef"
},
"type": {
"type": "string"
"type": "integer",
"format": "int32"
},
"value": {
"type": "string",
Expand Down
8 changes: 4 additions & 4 deletions pkg/apis/pipeline/v1beta1/task_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ import (

const (
// TaskRunResultType default task run result value
TaskRunResultType ResultType = "TaskRunResult"
TaskRunResultType ResultType = 1
// PipelineResourceResultType default pipeline result value
PipelineResourceResultType ResultType = "PipelineResourceResult"
PipelineResourceResultType = 2
// InternalTektonResultType default internal tekton result value
InternalTektonResultType ResultType = "InternalTektonResult"
InternalTektonResultType = 3
// UnknownResultType default unknown result type value
UnknownResultType ResultType = ""
UnknownResultType = 10
)

// +genclient
Expand Down
57 changes: 47 additions & 10 deletions pkg/pod/status_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,7 @@ func TestMakeTaskRunStatus(t *testing.T) {
Name: "step-bar",
State: corev1.ContainerState{
Terminated: &corev1.ContainerStateTerminated{
Message: `[{"key":"resultName","value":"resultValue", "type": "TaskRunResult"}, {"key":"digest","value":"sha256:1234","resourceRef":{"name":"source-image"}}]`,
Message: `[{"key":"resultName","value":"resultValue", "type":1}, {"key":"digest","value":"sha256:1234","resourceRef":{"name":"source-image"}}]`,
},
},
}},
Expand All @@ -560,7 +560,7 @@ func TestMakeTaskRunStatus(t *testing.T) {
Steps: []v1beta1.StepState{{
ContainerState: corev1.ContainerState{
Terminated: &corev1.ContainerStateTerminated{
Message: `[{"key":"digest","value":"sha256:1234","resourceRef":{"name":"source-image"}},{"key":"resultName","value":"resultValue","type":"TaskRunResult"}]`,
Message: `[{"key":"digest","value":"sha256:1234","resourceRef":{"name":"source-image"}},{"key":"resultName","value":"resultValue","type":1}]`,
}},
Name: "bar",
ContainerName: "step-bar",
Expand All @@ -587,7 +587,7 @@ func TestMakeTaskRunStatus(t *testing.T) {
Name: "step-banana",
State: corev1.ContainerState{
Terminated: &corev1.ContainerStateTerminated{
Message: `[{"key":"resultName","value":"resultValue", "type": "TaskRunResult"}, {"key":"digest","value":"sha256:1234","resourceRef":{"name":"source-image"}}]`,
Message: `[{"key":"resultName","value":"resultValue", "type":1}, {"key":"digest","value":"sha256:1234","resourceRef":{"name":"source-image"}}]`,
},
},
}},
Expand All @@ -598,7 +598,7 @@ func TestMakeTaskRunStatus(t *testing.T) {
Steps: []v1beta1.StepState{{
ContainerState: corev1.ContainerState{
Terminated: &corev1.ContainerStateTerminated{
Message: `[{"key":"digest","value":"sha256:1234","resourceRef":{"name":"source-image"}},{"key":"resultName","value":"resultValue","type":"TaskRunResult"}]`,
Message: `[{"key":"digest","value":"sha256:1234","resourceRef":{"name":"source-image"}},{"key":"resultName","value":"resultValue","type":1}]`,
}},
Name: "banana",
ContainerName: "step-banana",
Expand All @@ -625,14 +625,14 @@ func TestMakeTaskRunStatus(t *testing.T) {
Name: "step-one",
State: corev1.ContainerState{
Terminated: &corev1.ContainerStateTerminated{
Message: `[{"key":"resultNameOne","value":"resultValueOne", "type": "TaskRunResult"}, {"key":"resultNameTwo","value":"resultValueTwo", "type": "TaskRunResult"}]`,
Message: `[{"key":"resultNameOne","value":"resultValueOne", "type":1}, {"key":"resultNameTwo","value":"resultValueTwo", "type":1}]`,
},
},
}, {
Name: "step-two",
State: corev1.ContainerState{
Terminated: &corev1.ContainerStateTerminated{
Message: `[{"key":"resultNameOne","value":"resultValueThree","type":"TaskRunResult"},{"key":"resultNameTwo","value":"resultValueTwo","type":"TaskRunResult"}]`,
Message: `[{"key":"resultNameOne","value":"resultValueThree","type":1},{"key":"resultNameTwo","value":"resultValueTwo","type":1}]`,
},
},
}},
Expand All @@ -643,14 +643,14 @@ func TestMakeTaskRunStatus(t *testing.T) {
Steps: []v1beta1.StepState{{
ContainerState: corev1.ContainerState{
Terminated: &corev1.ContainerStateTerminated{
Message: `[{"key":"resultNameOne","value":"resultValueOne","type":"TaskRunResult"},{"key":"resultNameTwo","value":"resultValueTwo","type":"TaskRunResult"}]`,
Message: `[{"key":"resultNameOne","value":"resultValueOne","type":1},{"key":"resultNameTwo","value":"resultValueTwo","type":1}]`,
}},
Name: "one",
ContainerName: "step-one",
}, {
ContainerState: corev1.ContainerState{
Terminated: &corev1.ContainerStateTerminated{
Message: `[{"key":"resultNameOne","value":"resultValueThree","type":"TaskRunResult"},{"key":"resultNameTwo","value":"resultValueTwo","type":"TaskRunResult"}]`,
Message: `[{"key":"resultNameOne","value":"resultValueThree","type":1},{"key":"resultNameTwo","value":"resultValueTwo","type":1}]`,
}},
Name: "two",
ContainerName: "step-two",
Expand Down Expand Up @@ -721,6 +721,43 @@ func TestMakeTaskRunStatus(t *testing.T) {
},
}, {
desc: "filter internaltektonresult",
podStatus: corev1.PodStatus{
Phase: corev1.PodSucceeded,
ContainerStatuses: []corev1.ContainerStatus{{
Name: "step-pear",
State: corev1.ContainerState{
Terminated: &corev1.ContainerStateTerminated{
Message: `[{"key":"resultNameOne","value":"","type":2}, {"key":"resultNameTwo","value":"","type":3}, {"key":"resultNameThree","value":"","type":1}]`},
},
}},
},
want: v1beta1.TaskRunStatus{
Status: statusSuccess(),
TaskRunStatusFields: v1beta1.TaskRunStatusFields{
Steps: []v1beta1.StepState{{
ContainerState: corev1.ContainerState{
Terminated: &corev1.ContainerStateTerminated{
Message: `[{"key":"resultNameOne","value":"","type":2},{"key":"resultNameThree","value":"","type":1}]`,
}},
Name: "pear",
ContainerName: "step-pear",
}},
Sidecars: []v1beta1.SidecarState{},
ResourcesResult: []v1beta1.PipelineResourceResult{{
Key: "resultNameOne",
Value: "",
ResultType: v1beta1.PipelineResourceResultType,
}},
TaskRunResults: []v1beta1.TaskRunResult{{
Name: "resultNameThree",
Value: "",
}},
// We don't actually care about the time, just that it's not nil
CompletionTime: &metav1.Time{Time: time.Now()},
},
},
}, {
desc: "filter internaltektonresult with `type` as string",
podStatus: corev1.PodStatus{
Phase: corev1.PodSucceeded,
ContainerStatuses: []corev1.ContainerStatus{{
Expand All @@ -738,7 +775,7 @@ func TestMakeTaskRunStatus(t *testing.T) {
Steps: []v1beta1.StepState{{
ContainerState: corev1.ContainerState{
Terminated: &corev1.ContainerStateTerminated{
Message: `[{"key":"resultNameOne","value":"","type":"PipelineResourceResult"},{"key":"resultNameThree","value":"","type":"TaskRunResult"}]`,
Message: `[{"key":"resultNameOne","value":"","type":2},{"key":"resultNameThree","value":"","type":1}]`,
}},
Name: "pear",
ContainerName: "step-pear",
Expand All @@ -747,7 +784,7 @@ func TestMakeTaskRunStatus(t *testing.T) {
ResourcesResult: []v1beta1.PipelineResourceResult{{
Key: "resultNameOne",
Value: "",
ResultType: "PipelineResourceResult",
ResultType: v1beta1.PipelineResourceResultType,
}},
TaskRunResults: []v1beta1.TaskRunResult{{
Name: "resultNameThree",
Expand Down

0 comments on commit d21e087

Please sign in to comment.