1package main 2 3import ( 4 "bytes" 5 "context" 6 "fmt" 7 "log" 8 "sync" 9 "time" 10 11 "github.com/golang/protobuf/proto" 12 "github.com/golang/protobuf/ptypes" 13 harness "github.com/envoyproxy/protoc-gen-validate/tests/harness/go" 14) 15 16func Work(wg *sync.WaitGroup, in <-chan TestCase, out chan<- TestResult, goFlag bool, gogoFlag bool, ccFlag bool, javaFlag bool) { 17 for tc := range in { 18 ok, skip := execTestCase(tc, goFlag, gogoFlag, ccFlag, javaFlag) 19 out <- TestResult{ok, skip} 20 } 21 wg.Done() 22} 23 24func execTestCase(tc TestCase, goFlag bool, gogoFlag bool, ccFlag bool, javaFlag bool) (ok, skip bool) { 25 any, err := ptypes.MarshalAny(tc.Message) 26 if err != nil { 27 log.Printf("unable to convert test case %q to Any - %v", tc.Name, err) 28 return false, false 29 } 30 31 b, err := proto.Marshal(&harness.TestCase{Message: any}) 32 if err != nil { 33 log.Printf("unable to marshal test case %q - %v", tc.Name, err) 34 return false, false 35 } 36 37 ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) 38 defer cancel() 39 40 harnesses := Harnesses(goFlag, gogoFlag, ccFlag, javaFlag) 41 42 wg := new(sync.WaitGroup) 43 wg.Add(len(harnesses)) 44 45 errs := make(chan error, len(harnesses)) 46 skips := make(chan string, len(harnesses)) 47 48 for _, h := range harnesses { 49 h := h 50 go func() { 51 defer wg.Done() 52 53 res, err := h.Exec(ctx, bytes.NewReader(b)) 54 if err != nil { 55 errs <- err 56 return 57 } 58 59 if res.Error { 60 errs <- fmt.Errorf("%s: internal harness error: %s", h.Name, res.Reason) 61 } else if res.Valid != tc.Valid { 62 if res.AllowFailure { 63 skips <- fmt.Sprintf("%s: ignoring test failure: %s", h.Name, res.Reason) 64 } else if tc.Valid { 65 errs <- fmt.Errorf("%s: expected valid, got: %s", h.Name, res.Reason) 66 } else { 67 errs <- fmt.Errorf("%s: expected invalid, but got valid", h.Name) 68 } 69 } 70 }() 71 } 72 73 wg.Wait() 74 close(errs) 75 close(skips) 76 77 ok = true 78 79 for err := range errs { 80 log.Printf("[%s] %v", tc.Name, err) 81 ok = false 82 } 83 for out := range skips { 84 log.Printf("[%s] %v", tc.Name, out) 85 skip = true 86 } 87 88 return 89} 90