blob: 95d86467f5f2e2f17da106ed3ea1f5de7275b252 [file] [log] [blame]
// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
// This file contains helper functions related to running shell commands in tests.
import (
"bytes"
"io"
"os"
"os/exec"
"testing"
)
// runCmd handles the boilerplate associated with running an exec.Cmd object.
// In particular, it handles wiring up the std{out,err} pipes, reading from them,
// and checking errors. runCmd doesn't return error because errors are reported
// on the testing object. runCmd returns the stdout and stderr as strings.
func runCmd(t *testing.T, cmd *exec.Cmd, failureExpected bool) (string, string) {
// Make sure go is in the path.
_, err := exec.LookPath(cmd.Path)
if err != nil {
t.Fatal(err)
}
// Wire up output pipes.
stderr, err := cmd.StderrPipe()
if err != nil {
t.Fatal(err)
}
stdout, err := cmd.StdoutPipe()
if err != nil {
t.Fatal(err)
}
// Using .Start() is required when fetching output from pipes.
if err = cmd.Start(); err != nil {
t.Fatal(err)
}
// Reading from pipes is required before calling .Wait().
outBytes, err := io.ReadAll(stdout)
if err != nil {
t.Fatal(err)
}
errBytes, err := io.ReadAll(stderr)
if err != nil {
t.Fatal(err)
}
if len(outBytes) > 0 || len(errBytes) > 0 {
t.Logf("Command (%s) has output\nFull command: %v\n", cmd.Path, cmd.Args)
}
if len(outBytes) > 0 {
t.Logf("Stdout:\n%s\n", string(outBytes))
}
if len(errBytes) > 0 {
t.Logf("Stderr:\n%s\n", string(errBytes))
}
// Wait for it...
if err = cmd.Wait(); err != nil {
if !failureExpected {
t.Fatal(err)
}
}
return string(outBytes), string(errBytes)
}
func runfunc(f func()) (string, string, error) {
oldout, olderr := os.Stdout, os.Stderr
defer func() {
os.Stdout, os.Stderr = oldout, olderr
}()
reader, writer, err := os.Pipe()
if err != nil {
return "", "", err
}
errReader, errWriter, err := os.Pipe()
if err != nil {
return "", "", err
}
os.Stdout, os.Stderr = writer, errWriter
f()
writer.Close()
errWriter.Close()
var outbuf, errbuf bytes.Buffer
io.Copy(&outbuf, reader)
io.Copy(&errbuf, errReader)
return outbuf.String(), errbuf.String(), nil
}