test: add pipe checker to test dir

The pipe checker is an attempt at replicating how one would go to write
commands on a CLI and piping them together, coupled with a `test`.
pull/13032/head
Lucas Bajolet 2 years ago committed by Lucas Bajolet
parent 75e4a47686
commit b32ef74941

@ -0,0 +1,86 @@
package test
import "fmt"
// Pipe is any command that allows piping two gadgets together
//
// There's always only one input and one output (stdout), mimicking essentially
// how pipes work in the UNIX-world.
type Pipe interface {
Process(input string) (string, error)
}
// CustomPipe allows providing a simple function for piping inputs together
type CustomPipe func(string) (string, error)
func (c CustomPipe) Process(input string) (string, error) {
return c(input)
}
// Tester is the end of a pipe for testing purposes.
//
// Once multiple commands have been piped together in a pipeline, we can
// perform some checks on that input, and decide if a test is a success or a
// failure.
type Tester interface {
Check(input string) error
}
// CustomTester allows providing a function to check that the input is what we want
type CustomTester func(string) error
func (ct CustomTester) Check(input string) error {
return ct(input)
}
// PipeChecker is a kind of checker that essentially lets users write mini
// gadgets that pipe inputs together, and compose those to end as a true/false
// statement, which translates to an error.
//
// Unlike pipes in a real command-line context, since we're dealing with
// finite gadgets to process data, we're sequentially running their Process
// function, and any processor that ends in an error will make the pipeline
// fail.
//
// Stream is provided so we know if we want to combine stdout/stderr for the
// pipeline, or if we want only to focus on either.
type PipeChecker struct {
name string
stream Stream
pipers []Pipe
check Tester
}
func (pc PipeChecker) Check(stdout, stderr string, _ error) error {
if len(pc.pipers) == 0 {
return fmt.Errorf("%s - empty pipeline", pc.Name())
}
var pipeStr string
switch pc.stream {
case OnlyStdout:
pipeStr = stdout
case OnlyStderr:
pipeStr = stderr
case BothStreams:
pipeStr = fmt.Sprintf("%s\n%s", stdout, stderr)
}
var err error
for i, pp := range pc.pipers {
pipeStr, err = pp.Process(pipeStr)
if err != nil {
return fmt.Errorf("pipeline failed during execution (%d): %s", i, err)
}
}
return pc.check.Check(pipeStr)
}
func (pc PipeChecker) Name() string {
rawName := "|>?"
if pc.name != "" {
rawName = fmt.Sprintf("%s - %s", rawName, pc.name)
}
return rawName
}
Loading…
Cancel
Save