[tint] Read stdout and stderr asynchronously in E2E test runner
This avoids issues with very large output on one pipe being buffered
and blocking progress reading from the other pipe.
Bug: 429625133
Change-Id: I33db4e10f15cdc7bcd5f93fc2f41a68224cd573d
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/251514
Commit-Queue: James Price <jrprice@google.com>
Auto-Submit: James Price <jrprice@google.com>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
Commit-Queue: dan sinclair <dsinclair@chromium.org>
diff --git a/tools/src/cmd/tests/main.go b/tools/src/cmd/tests/main.go
index 9104f11..b2aa927 100644
--- a/tools/src/cmd/tests/main.go
+++ b/tools/src/cmd/tests/main.go
@@ -1033,21 +1033,37 @@
result := make(chan testResult, 1)
go func() {
// Send the test arguments to the Tint server.
- _, in_err := tintServer.stdin.Write([]byte("\"" + strings.Join(args, "\" \"") + "\"\n"))
+ _, inErr := tintServer.stdin.Write([]byte("\"" + strings.Join(args, "\" \"") + "\"\n"))
// Read from stdout and stderr until the next null character.
- read := func(stream io.ReadCloser) (str string, err error) {
- reader := bufio.NewReader(stream)
- result, err := reader.ReadString(0)
- return strings.TrimSuffix(result, "\x00"), err
+ // Perform these as two asynchronous operations to prevent buffering of large output from
+ // blocking progress.
+ type readResult struct {
+ str string
+ err error
}
- stdout_str, out_err := read(tintServer.stdout)
- stderr_str, err_err := read(tintServer.stderr)
- str := stderr_str + stdout_str
+ read := func(stream io.ReadCloser) chan readResult {
+ resultChannel := make(chan readResult, 1)
+ go func() {
+ reader := bufio.NewReader(stream)
+ result, err := reader.ReadString(0)
+ resultChannel <- readResult{strings.TrimSuffix(result, "\x00"), err}
+ }()
+ return resultChannel
+ }
+ stdoutChannel := read(tintServer.stdout)
+ stderrChannel := read(tintServer.stderr)
+
+ // Read the results from the channels.
+ stdoutResult := <-stdoutChannel
+ stderrResult := <-stderrChannel
+ stdoutStr, outErr := stdoutResult.str, stdoutResult.err
+ stderrStr, errErr := stderrResult.str, stderrResult.err
+ str := stderrStr + stdoutStr
result <- testResult{
output: str,
- ok: in_err == nil && out_err == nil && err_err == nil,
+ ok: inErr == nil && outErr == nil && errErr == nil,
}
}()