Fix stdin deadlock and exit code rewrite logic
This commit is contained in:
parent
909609f21f
commit
3730d8995c
9
run.go
9
run.go
|
|
@ -174,10 +174,8 @@ func runFile(file ShoutFile, opts RunOptions) FileResult {
|
|||
}
|
||||
}
|
||||
|
||||
_, _ = io.WriteString(stdin, script)
|
||||
stdin.Close()
|
||||
|
||||
// Read stdout with timeout
|
||||
// Read stdout with timeout — must start reader BEFORE writing to stdin
|
||||
// to avoid deadlock when pipe buffers fill in both directions.
|
||||
totalTimeout := opts.Timeout * time.Duration(len(file.Commands))
|
||||
type readResult struct {
|
||||
data []byte
|
||||
|
|
@ -189,6 +187,9 @@ func runFile(file ShoutFile, opts RunOptions) FileResult {
|
|||
ch <- readResult{data, err}
|
||||
}()
|
||||
|
||||
_, _ = io.WriteString(stdin, script)
|
||||
stdin.Close()
|
||||
|
||||
var output []byte
|
||||
select {
|
||||
case r := <-ch:
|
||||
|
|
|
|||
53
update.go
53
update.go
|
|
@ -53,16 +53,45 @@ func rewriteFile(file ShoutFile, results []CommandResult, originalContent string
|
|||
}
|
||||
}
|
||||
|
||||
// If wildcards match, keep original
|
||||
if matchOutput(cmd.Expected, result.Actual) {
|
||||
outputMatch := matchOutput(cmd.Expected, result.Actual)
|
||||
ecMatch := exitCodeOK(cmd.ExitCodeType, cmd.ExitCodeValue, result.ExitCode)
|
||||
|
||||
if outputMatch && ecMatch {
|
||||
// Both match — preserve original verbatim
|
||||
output = append(output, oldExpectedRaw...)
|
||||
} else if outputMatch {
|
||||
// Output matches but exit code changed — preserve output, fix exit code
|
||||
raw := oldExpectedRaw
|
||||
rawTrailing := 0
|
||||
for k := len(raw) - 1; k >= 0; k-- {
|
||||
if raw[k] == "" {
|
||||
rawTrailing++
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
content := raw[:len(raw)-rawTrailing]
|
||||
// Strip old exit code marker if present
|
||||
if len(content) > 0 && exitCodeMarkerRe.MatchString(content[len(content)-1]) {
|
||||
content = content[:len(content)-1]
|
||||
}
|
||||
output = append(output, content...)
|
||||
marker := updateExitCodeMarker(cmd, result.ExitCode)
|
||||
if marker != "" {
|
||||
output = append(output, marker)
|
||||
} else if len(content) > 0 && exitCodeMarkerRe.MatchString(content[len(content)-1]) {
|
||||
output = append(output, "[0]")
|
||||
}
|
||||
for k := 0; k < rawTrailing; k++ {
|
||||
output = append(output, "")
|
||||
}
|
||||
} else {
|
||||
// Output doesn't match — rewrite everything
|
||||
output = append(output, result.Actual...)
|
||||
if result.ExitCode != 0 {
|
||||
output = append(output, fmt.Sprintf("[%d]", result.ExitCode))
|
||||
marker := updateExitCodeMarker(cmd, result.ExitCode)
|
||||
if marker != "" {
|
||||
output = append(output, marker)
|
||||
} else if len(result.Actual) > 0 && exitCodeMarkerRe.MatchString(result.Actual[len(result.Actual)-1]) {
|
||||
// Actual output's last line looks like an exit code marker.
|
||||
// Add an explicit [0] to prevent parser from consuming it.
|
||||
output = append(output, "[0]")
|
||||
}
|
||||
for k := 0; k < trailingBlanks; k++ {
|
||||
|
|
@ -79,3 +108,15 @@ func rewriteFile(file ShoutFile, results []CommandResult, originalContent string
|
|||
|
||||
return strings.Join(output, "\n")
|
||||
}
|
||||
|
||||
// updateExitCodeMarker returns the exit code marker to write, preserving [*]
|
||||
// wildcards when the command still exits non-zero.
|
||||
func updateExitCodeMarker(cmd Command, actualExitCode int) string {
|
||||
if cmd.ExitCodeType == ExitCodeWildcard && actualExitCode != 0 {
|
||||
return "[*]"
|
||||
}
|
||||
if actualExitCode != 0 {
|
||||
return fmt.Sprintf("[%d]", actualExitCode)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user