clipper/backend/media/test_helper_test.go

104 lines
2.8 KiB
Go

package media_test
import (
"context"
"fmt"
"io"
"os"
"os/exec"
"strconv"
"strings"
"testing"
"git.netflux.io/rob/clipper/media"
"github.com/stretchr/testify/require"
"go.uber.org/zap"
)
// fixtureReader loads a fixture into a ReadCloser with the provided limit.
func fixtureReader(t *testing.T, fixturePath string, limit int64) io.ReadCloser {
fptr, err := os.Open(fixturePath)
require.NoError(t, err)
// limitReader to make the mock work realistically, not intended for assertions:
return struct {
io.Reader
io.Closer
}{
Reader: io.LimitReader(fptr, limit),
Closer: fptr,
}
}
// helperCommand returns a function that builds an *exec.Cmd which executes a
// test function in order to act as a mock process.
func helperCommand(t *testing.T, wantCommand, stdoutFile, stderrString string, forceExitCode int) media.CommandFunc {
return func(ctx context.Context, name string, args ...string) *exec.Cmd {
cs := []string{"-test.run=TestHelperProcess", "--", name}
cs = append(cs, args...)
cmd := exec.CommandContext(ctx, os.Args[0], cs...)
cmd.Env = []string{
"GO_WANT_HELPER_PROCESS=1",
"GO_WANT_COMMAND=" + wantCommand,
"GO_STDOUT_FILE=" + stdoutFile,
"GO_STDERR_STRING=" + stderrString,
"GO_FORCE_EXIT_CODE=" + strconv.Itoa(forceExitCode),
}
return cmd
}
}
// TestHelperProcess is the body for the mock executable process built by
// helperCommand.
func TestHelperProcess(t *testing.T) {
if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" {
return
}
defer func() {
// Stop the helper process writing to stdout after the test has finished.
// This prevents it from writing the "PASS" string which is unwanted in
// this context.
if !t.Failed() {
os.Stdout, _ = os.Open(os.DevNull)
}
}()
if exitCode := os.Getenv("GO_FORCE_EXIT_CODE"); exitCode != "0" {
c, _ := strconv.Atoi(exitCode)
os.Stderr.WriteString(os.Getenv("GO_STDERR_STRING"))
os.Exit(c)
}
if wantCommand := os.Getenv("GO_WANT_COMMAND"); wantCommand != "" {
_, gotCmd, _ := strings.Cut(strings.Join(os.Args, " "), " -- ")
if wantCommand != gotCmd {
fmt.Fprintf(os.Stderr, "GO_WANT_COMMAND assertion failed:\nwant = %v\ngot = %v", wantCommand, gotCmd)
t.Fail() // necessary to make the test fail
}
}
// Copy stdin to /dev/null. This is required to avoid broken pipe errors in
// the tests:
_, err := io.Copy(io.Discard, os.Stdin)
require.NoError(t, err)
// If an output file is provided, then copy that to stdout:
if fname := os.Getenv("GO_STDOUT_FILE"); fname != "" {
fptr, err := os.Open(fname)
require.NoError(t, err)
defer fptr.Close()
_, err = io.Copy(os.Stdout, fptr)
require.NoError(t, err)
}
}
// testLogger returns a functional development logger.
//lint:ignore U1000 helper method
func testLogger(t *testing.T) *zap.Logger {
l, err := zap.NewDevelopment()
require.NoError(t, err)
return l
}