123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- package main
- import (
- "bufio"
- "bytes"
- "fmt"
- "io"
- "os"
- "os/exec"
- "runtime"
- "strings"
- "sync"
- harness "github.com/envoyproxy/protoc-gen-validate/tests/harness/go"
- "golang.org/x/net/context"
- "google.golang.org/protobuf/proto"
- )
- func Harnesses(goFlag, ccFlag, javaFlag, pythonFlag bool, externalHarnessFlag string) []Harness {
- harnesses := make([]Harness, 0)
- if goFlag {
- harnesses = append(harnesses, InitHarness("tests/harness/go/main/go-harness", "go"))
- }
- if ccFlag {
- harnesses = append(harnesses, InitHarness("tests/harness/cc/cc-harness", "cc"))
- }
- if javaFlag {
- harnesses = append(harnesses, InitHarness("tests/harness/java/java-harness", "java"))
- }
- if pythonFlag {
- harnesses = append(harnesses, InitHarness("tests/harness/python/python-harness", "python"))
- }
- if externalHarnessFlag != "" {
- harnesses = append(harnesses, InitHarness(externalHarnessFlag, "external"))
- }
- return harnesses
- }
- type Harness struct {
- Name string
- Exec func(context.Context, io.Reader) (*harness.TestResult, error)
- }
- func InitHarness(cmd string, name string, args ...string) Harness {
- if runtime.GOOS == "windows" {
- // Bazel runfiles are not symlinked in on windows,
- // so we have to use the manifest instead. If the manifest
- // doesn't exist, assume we're running in a non-Bazel context
- f, err := os.Open("MANIFEST")
- if err == nil {
- defer f.Close()
- s := bufio.NewScanner(f)
- manifest := map[string]string{}
- for s.Scan() {
- values := strings.Split(s.Text(), " ")
- manifest[values[0]] = values[1]
- }
- for k, v := range manifest {
- if strings.Contains(k, cmd) {
- cmd = v
- }
- }
- }
- }
- return Harness{
- Name: name,
- Exec: initHarness(cmd, args...),
- }
- }
- func initHarness(cmd string, args ...string) func(context.Context, io.Reader) (*harness.TestResult, error) {
- return func(ctx context.Context, r io.Reader) (*harness.TestResult, error) {
- out, errs := getBuf(), getBuf()
- defer relBuf(out)
- defer relBuf(errs)
- cmd := exec.CommandContext(ctx, cmd, args...)
- cmd.Stdin = r
- cmd.Stdout = out
- cmd.Stderr = errs
- if err := cmd.Run(); err != nil {
- return nil, fmt.Errorf("[%s] failed execution (%v) - captured stderr:\n%s", cmdStr(cmd), err, errs.String())
- }
- if errs.Len() > 0 {
- fmt.Printf("captured stderr:\n%s", errs.String())
- }
- res := new(harness.TestResult)
- if err := proto.Unmarshal(out.Bytes(), res); err != nil {
- return nil, fmt.Errorf("[%s] failed to unmarshal result: %v", cmdStr(cmd), err)
- }
- return res, nil
- }
- }
- var bufPool = &sync.Pool{New: func() interface{} { return new(bytes.Buffer) }}
- func getBuf() *bytes.Buffer {
- return bufPool.Get().(*bytes.Buffer)
- }
- func relBuf(b *bytes.Buffer) {
- b.Reset()
- bufPool.Put(b)
- }
- func cmdStr(cmd *exec.Cmd) string {
- return fmt.Sprintf("%s %s", cmd.Path, strings.Join(cmd.Args, " "))
- }
|