Skip to content

Commit 4d9a5bb

Browse files
allow captures from truncated command output
1 parent b42fa70 commit 4d9a5bb

2 files changed

Lines changed: 63 additions & 34 deletions

File tree

‎checks/cli.go‎

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -118,10 +118,7 @@ func runCLICommandWithOutputLimit(
118118
result.Stdout = ExtractTmdlBlock(result.Stdout, *command.StdoutFilterTmdl)
119119
}
120120

121-
if stdout.truncated || stderr.truncated {
122-
result.Err = fmt.Sprintf("command output exceeded the %d-byte per-stream limit", maxOutputBytesPerStream)
123-
result.ExitCode = -2
124-
} else if err := parseStdoutVariables(result.Stdout, command.StdoutVariables, captured); err != nil {
121+
if err := parseStdoutVariables(result.Stdout, command.StdoutVariables, captured); err != nil {
125122
result.Err = err.Error()
126123
}
127124
return result

‎checks/cli_test.go‎

Lines changed: 62 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,43 +2,75 @@ package checks
22

33
import (
44
"runtime"
5-
"strings"
65
"testing"
76

87
api "github.com/bootdotdev/bootdev/client"
98
)
109

1110
func TestRunCLICommandCapsOutput(t *testing.T) {
12-
command := `printf 'abcdefgh'`
13-
if runtime.GOOS == "windows" {
14-
command = `[Console]::Out.Write('abcdefgh')`
15-
}
16-
17-
variables := map[string]string{}
18-
result := runCLICommandWithOutputLimit(
19-
api.CLIStepCLICommand{
20-
Command: command,
21-
StdoutVariables: []api.CLICommandStdoutVariable{{
22-
Name: "partial",
23-
Regex: `(abcd)`,
24-
}},
11+
for _, tc := range []struct {
12+
name, command, windowsCommand, stdout, stderr, pattern, value string
13+
exitCode int
14+
wantFailure bool
15+
}{
16+
{
17+
name: "stdout overflow",
18+
command: `printf 'abcdefgh'`,
19+
windowsCommand: `[Console]::Out.Write('abcdefgh')`,
20+
stdout: "abcd", pattern: `^(abcd)$`, value: "abcd",
2521
},
26-
variables,
27-
4,
28-
defaultShell(),
29-
)
30-
31-
if !strings.Contains(result.Err, "per-stream limit") {
32-
t.Fatalf("command error = %q, want per-stream output limit error", result.Err)
33-
}
34-
if result.ExitCode >= 0 {
35-
t.Fatalf("exit code = %d, want internal failure", result.ExitCode)
36-
}
37-
if result.Stdout != "abcd" {
38-
t.Fatalf("stdout = %q, want capped output %q", result.Stdout, "abcd")
39-
}
40-
if _, ok := variables["partial"]; ok {
41-
t.Fatal("truncated output unexpectedly populated a stdout variable")
22+
{
23+
name: "stderr overflow",
24+
command: `printf 'ok'; printf 'abcdefgh' >&2`,
25+
windowsCommand: `[Console]::Out.Write('ok'); [Console]::Error.Write('abcdefgh')`,
26+
stdout: "ok", stderr: "abcd", pattern: `^(ok)$`, value: "ok",
27+
},
28+
{
29+
name: "nonzero exit",
30+
command: `printf 'abcdefgh'; exit 7`,
31+
windowsCommand: `[Console]::Out.Write('abcdefgh'); exit 7`,
32+
stdout: "abcd", pattern: `^(abcd)$`, value: "abcd", exitCode: 7,
33+
},
34+
{
35+
name: "capture beyond limit",
36+
command: `printf 'abcdefgh'`,
37+
windowsCommand: `[Console]::Out.Write('abcdefgh')`,
38+
stdout: "abcd", pattern: `(efgh)`, wantFailure: true,
39+
},
40+
} {
41+
t.Run(tc.name, func(t *testing.T) {
42+
command := tc.command
43+
if runtime.GOOS == "windows" {
44+
command = tc.windowsCommand
45+
}
46+
step := api.CLIStepCLICommand{
47+
Command: command,
48+
StdoutVariables: []api.CLICommandStdoutVariable{{Name: "token", Regex: tc.pattern}},
49+
}
50+
variables := map[string]string{"token": "old"}
51+
result := runCLICommandWithOutputLimit(step, variables, 4, defaultShell())
52+
if result.ExitCode != tc.exitCode {
53+
t.Fatalf("exit code = %d, want %d", result.ExitCode, tc.exitCode)
54+
}
55+
if result.Stdout != tc.stdout || result.Stderr != tc.stderr {
56+
t.Fatalf("stdout/stderr = %q/%q, want %q/%q", result.Stdout, result.Stderr, tc.stdout, tc.stderr)
57+
}
58+
if tc.wantFailure {
59+
if result.Err == "" {
60+
t.Fatal("missing capture should fail")
61+
}
62+
if _, found := variables["token"]; found {
63+
t.Fatal("failed capture retained the old token")
64+
}
65+
return
66+
}
67+
if result.Err != "" {
68+
t.Fatalf("unexpected command error: %s", result.Err)
69+
}
70+
if variables["token"] != tc.value {
71+
t.Fatalf("capture = %q, want %q", variables["token"], tc.value)
72+
}
73+
})
4274
}
4375
}
4476

0 commit comments

Comments
 (0)