Skip to content

Commit

Permalink
feat: always print truncated function stderr (#2639)
Browse files Browse the repository at this point in the history
* feat: always print truncated function stderr

This change makes it so that kpt fn render|eval will always print
truncated stderr output from functions. This is intended to improve the
experience of debugging functions.

* test: add unit test cases for printFnStderr

* test: add e2e test for fn eval stderr

This test case is intended to check that kpt fn eval outputs the stderr
of the function even when the function succeeds. This is doing using a
simple function script which emits hello world to stderr.

* test: add e2e test for fn render stderr

This test case is intended to check that kpt fn render outputs the stderr
of the function even when the function succeeds. This is doing using a
simple function script which emits hello world to stderr.
  • Loading branch information
sdowell authored Jan 12, 2022
1 parent 2ca7220 commit 29e455c
Show file tree
Hide file tree
Showing 14 changed files with 295 additions and 3 deletions.
24 changes: 24 additions & 0 deletions e2e/testdata/fn-eval/exec-function-stderr/.expected/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

testType: eval
stdErr: |
[RUNNING] "./function.sh"
[PASS] "./function.sh" in 0s
Stderr:
"Hello world 0!"
"Hello world 1!"
"Hello world 2!"
"Hello world 3!"
...(18 line(s) truncated, use '--truncate-output=false' to disable)
21 changes: 21 additions & 0 deletions e2e/testdata/fn-eval/exec-function-stderr/.expected/diff.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
diff --git a/resources.yaml b/resources.yaml
index e8ae6bb..297b99f 100644
--- a/resources.yaml
+++ b/resources.yaml
@@ -15,7 +15,7 @@ apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
- namespace: foo
+ namespace: bar
spec:
replicas: 3
---
@@ -23,6 +23,6 @@ apiVersion: custom.io/v1
kind: Custom
metadata:
name: custom
- namespace: foo
+ namespace: bar
spec:
image: nginx:1.2.3
19 changes: 19 additions & 0 deletions e2e/testdata/fn-eval/exec-function-stderr/.expected/exec.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#! /bin/bash
# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

set -eo pipefail

kpt fn source \
| kpt fn eval --exec ./function.sh
1 change: 1 addition & 0 deletions e2e/testdata/fn-eval/exec-function-stderr/.krmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.expected
21 changes: 21 additions & 0 deletions e2e/testdata/fn-eval/exec-function-stderr/function.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#! /usr/bin/env bash
# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

sed -e 's/foo/bar/'

for i in {0..20}
do
>&2 echo "Hello world $i!"
done
28 changes: 28 additions & 0 deletions e2e/testdata/fn-eval/exec-function-stderr/resources.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
namespace: foo
spec:
replicas: 3
---
apiVersion: custom.io/v1
kind: Custom
metadata:
name: custom
namespace: foo
spec:
image: nginx:1.2.3
24 changes: 24 additions & 0 deletions e2e/testdata/fn-render/exec-function-stderr/.expected/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

allowExec: true
stdErr: |
[RUNNING] "./testdata/fn-render/exec-function-stderr/function.sh"
[PASS] "./testdata/fn-render/exec-function-stderr/function.sh" in 0s
Stderr:
"Hello world 0!"
"Hello world 1!"
"Hello world 2!"
"Hello world 3!"
...(18 line(s) truncated, use '--truncate-output=false' to disable)
21 changes: 21 additions & 0 deletions e2e/testdata/fn-render/exec-function-stderr/.expected/diff.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
diff --git a/resources.yaml b/resources.yaml
index e8ae6bb..297b99f 100644
--- a/resources.yaml
+++ b/resources.yaml
@@ -15,7 +15,7 @@ apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
- namespace: foo
+ namespace: bar
spec:
replicas: 3
---
@@ -23,6 +23,6 @@ apiVersion: custom.io/v1
kind: Custom
metadata:
name: custom
- namespace: foo
+ namespace: bar
spec:
image: nginx:1.2.3
1 change: 1 addition & 0 deletions e2e/testdata/fn-render/exec-function-stderr/.krmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.expected
7 changes: 7 additions & 0 deletions e2e/testdata/fn-render/exec-function-stderr/Kptfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
apiVersion: kpt.dev/v1
kind: Kptfile
metadata:
name: app
pipeline:
mutators:
- exec: "./testdata/fn-render/exec-function-stderr/function.sh"
21 changes: 21 additions & 0 deletions e2e/testdata/fn-render/exec-function-stderr/function.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#! /usr/bin/env bash
# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

sed -e 's/foo/bar/'

for i in {0..20}
do
>&2 echo "Hello world $i!"
done
28 changes: 28 additions & 0 deletions e2e/testdata/fn-render/exec-function-stderr/resources.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
namespace: foo
spec:
replicas: 3
---
apiVersion: custom.io/v1
kind: Custom
metadata:
name: custom
namespace: foo
spec:
image: nginx:1.2.3
13 changes: 10 additions & 3 deletions internal/fnruntime/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ func (fr *FunctionRunner) Filter(input []*yaml.RNode) (output []*yaml.RNode, err
if !fr.disableCLIOutput {
pr.Printf("[PASS] %q in %v\n", fr.name, time.Since(t0).Truncate(time.Millisecond*100))
printFnResult(fr.ctx, fr.fnResult, printer.NewOpt())
printFnStderr(fr.ctx, fr.fnResult.Stderr)
}
return output, err
}
Expand Down Expand Up @@ -345,16 +346,22 @@ func printFnResult(ctx context.Context, fnResult *fnresult.Result, opt *printer.
// on kpt CLI.
func printFnExecErr(ctx context.Context, fnErr *ExecError) {
pr := printer.FromContextOrDie(ctx)
if len(fnErr.Stderr) > 0 {
printFnStderr(ctx, fnErr.Stderr)
pr.Printf(" Exit code: %d\n\n", fnErr.ExitCode)
}

// printFnStderr prints given stdErr in a user friendly format on kpt CLI.
func printFnStderr(ctx context.Context, stdErr string) {
pr := printer.FromContextOrDie(ctx)
if len(stdErr) > 0 {
errLines := &multiLineFormatter{
Title: "Stderr",
Lines: strings.Split(fnErr.Stderr, "\n"),
Lines: strings.Split(stdErr, "\n"),
UseQuote: true,
TruncateOutput: printer.TruncateOutput,
}
pr.Printf("%s", errLines.String())
}
pr.Printf(" Exit code: %d\n\n", fnErr.ExitCode)
}

// path (location) of a KRM resources is tracked in a special key in
Expand Down
69 changes: 69 additions & 0 deletions internal/fnruntime/runner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@ package fnruntime

import (
"bytes"
"context"
"io/ioutil"
"os"
"path"
"strings"
"testing"

"github.com/GoogleContainerTools/kpt/internal/printer"
"github.com/GoogleContainerTools/kpt/internal/types"
kptfilev1 "github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1"
"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -577,3 +579,70 @@ file:
assert.Equal(t, tc.expected, string(out))
}
}

func TestPrintFnStderr(t *testing.T) {
tests := map[string]struct {
input string // input
truncateOutput bool // whether to truncate output
expected string // expected result
}{
"no output": {
input: ``,
truncateOutput: true,
expected: ``,
},
"truncated output": {
input: `0
1
2
3
4
5`,
truncateOutput: true,
expected: ` Stderr:
"0"
"1"
"2"
"3"
...(2 line(s) truncated, use '--truncate-output=false' to disable)
`,
},
"non-truncated output": {
input: `0
1
2
3
4
5`,
truncateOutput: false,
expected: ` Stderr:
"0"
"1"
"2"
"3"
"4"
"5"
`,
},
}
cleanupFunc := func() func() {
origTruncateOutput := printer.TruncateOutput
return func() {
printer.TruncateOutput = origTruncateOutput
}
}()
defer cleanupFunc()
for testName, tc := range tests {
t.Run(testName, func(t *testing.T) {
printer.TruncateOutput = tc.truncateOutput
out := &bytes.Buffer{}
err := &bytes.Buffer{}
ctx := printer.WithContext(context.Background(), printer.New(out, err))

printFnStderr(ctx, tc.input)

assert.Equal(t, tc.expected, err.String())
assert.Equal(t, "", out.String())
})
}
}

0 comments on commit 29e455c

Please sign in to comment.