[testrunner] Enable separation of test stdout and stderr streams

Existing testrunner output still combines this output into a single
stream, but this will allow us to move away from that in the future.

IN-699 #comment

Change-Id: I8d8d55d312a4e001b004901f54ac3719a17dd028
diff --git a/cmd/testrunner/main.go b/cmd/testrunner/main.go
index a0b742e..ba84262 100644
--- a/cmd/testrunner/main.go
+++ b/cmd/testrunner/main.go
@@ -261,9 +261,14 @@
 
 func runTest(ctx context.Context, test testsharder.Test, tester Tester) (*testrunner.TestResult, error) {
 	result := runtests.TestSuccess
-	output := new(bytes.Buffer)
-	multistdout := io.MultiWriter(output, os.Stdout)
-	multistderr := io.MultiWriter(output, os.Stderr)
+	stdout := new(bytes.Buffer)
+	stderr := new(bytes.Buffer)
+
+	// Fork the test's stdout and stderr streams to the test runner's stderr stream to
+	// make local debugging easier.  Writing both to stderr ensures that stdout only
+	// contains the test runner's TAP output stream.
+	multistdout := io.MultiWriter(stdout, os.Stderr)
+	multistderr := io.MultiWriter(stderr, os.Stderr)
 
 	startTime := time.Now()
 
@@ -277,7 +282,8 @@
 	// Record the test details in the summary.
 	return &testrunner.TestResult{
 		Name:      test.Name,
-		Output:    output,
+		Stdout:    stdout.Bytes(),
+		Stderr:    stderr.Bytes(),
 		Result:    result,
 		StartTime: startTime,
 		EndTime:   endTime,
diff --git a/cmd/testrunner/output.go b/cmd/testrunner/output.go
index 232aed0..6a15c3f 100644
--- a/cmd/testrunner/output.go
+++ b/cmd/testrunner/output.go
@@ -6,6 +6,7 @@
 
 import (
 	"archive/tar"
+	"bytes"
 	"fmt"
 	"io"
 	"os"
@@ -25,7 +26,9 @@
 
 func (o *TarOutput) Record(result testrunner.TestResult) {
 	pathInArchive := path.Join(result.Name, runtests.TestOutputFilename)
-	botanist.ArchiveReader(o.w, result.Output, pathInArchive)
+	stdout := bytes.NewReader(result.Stdout)
+	stderr := bytes.NewReader(result.Stderr)
+	botanist.ArchiveReader(o.w, io.MultiReader(stdout, stderr), pathInArchive)
 }
 
 // TarFile adds a file to the underlying archive.
diff --git a/cmd/testrunner/output_test.go b/cmd/testrunner/output_test.go
index db0b6a1..c5e8890 100644
--- a/cmd/testrunner/output_test.go
+++ b/cmd/testrunner/output_test.go
@@ -27,7 +27,7 @@
 			name: "archive entry for test_a",
 			input: testrunner.TestResult{
 				Name:   "test_a",
-				Output: strings.NewReader("the test passed"),
+				Stdout: []byte("the test passed"),
 				Result: runtests.TestSuccess,
 			},
 			expectedHeader: &tar.Header{
@@ -43,7 +43,7 @@
 			name: "archive entry for test_b",
 			input: testrunner.TestResult{
 				Name:   "test_b",
-				Output: strings.NewReader("the test failed"),
+				Stdout: []byte("the test failed"),
 				Result: runtests.TestSuccess,
 			},
 			expectedHeader: &tar.Header{
diff --git a/testrunner/result.go b/testrunner/result.go
index f0a23ff..6753176 100644
--- a/testrunner/result.go
+++ b/testrunner/result.go
@@ -1,7 +1,6 @@
 package testrunner
 
 import (
-	"io"
 	"time"
 
 	"fuchsia.googlesource.com/tools/runtests"
@@ -12,12 +11,11 @@
 	// Name is the name of the test that was executed.
 	Name string
 
-	// Output is the test's combined stdout and stderr streams.
-	Output io.Reader
-
 	// Result describes whether the test passed or failed.
 	Result runtests.TestResult
 
+	Stdout    []byte
+	Stderr    []byte
 	StartTime time.Time
 	EndTime   time.Time
 }