[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, } }()