worker.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. package main
  2. import (
  3. "bytes"
  4. "context"
  5. "log"
  6. "strings"
  7. "sync"
  8. "time"
  9. harness "github.com/envoyproxy/protoc-gen-validate/tests/harness/go"
  10. "google.golang.org/protobuf/proto"
  11. "google.golang.org/protobuf/types/known/anypb"
  12. )
  13. func Work(wg *sync.WaitGroup, in <-chan TestCase, out chan<- TestResult, harnesses []Harness) {
  14. for tc := range in {
  15. execTestCase(tc, harnesses, out)
  16. }
  17. wg.Done()
  18. }
  19. func execTestCase(tc TestCase, harnesses []Harness, out chan<- TestResult) {
  20. any, err := anypb.New(tc.Message)
  21. if err != nil {
  22. log.Printf("unable to convert test case %q to Any - %v", tc.Name, err)
  23. out <- TestResult{false, false}
  24. return
  25. }
  26. b, err := proto.Marshal(&harness.TestCase{Message: any})
  27. if err != nil {
  28. log.Printf("unable to marshal test case %q - %v", tc.Name, err)
  29. out <- TestResult{false, false}
  30. return
  31. }
  32. ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
  33. defer cancel()
  34. wg := new(sync.WaitGroup)
  35. wg.Add(len(harnesses))
  36. for _, h := range harnesses {
  37. h := h
  38. go func() {
  39. defer wg.Done()
  40. res, err := h.Exec(ctx, bytes.NewReader(b))
  41. if err != nil {
  42. log.Printf("[%s] (%s harness) executor error: %s", tc.Name, h.Name, err.Error())
  43. out <- TestResult{false, false}
  44. return
  45. }
  46. if res.Error {
  47. log.Printf("[%s] (%s harness) internal harness error: %s", tc.Name, h.Name, res.Reasons)
  48. out <- TestResult{false, false}
  49. return
  50. }
  51. // Backwards compatibility for languages with no multi-error
  52. // feature: check results of validation in "fail fast" mode only
  53. if !res.CheckMultipleErrors {
  54. tcValid := tc.Failures == 0
  55. if res.Valid != tcValid {
  56. if res.AllowFailure {
  57. log.Printf("[%s] (%s harness) ignoring test failure: %v", tc.Name, h.Name, res.Reasons)
  58. out <- TestResult{false, true}
  59. } else if tcValid {
  60. log.Printf("[%s] (%s harness) expected valid, got invalid: %v", tc.Name, h.Name, res.Reasons)
  61. out <- TestResult{false, false}
  62. } else {
  63. log.Printf("[%s] (%s harness) expected invalid, got valid: %v", tc.Name, h.Name, res.Reasons)
  64. out <- TestResult{false, false}
  65. }
  66. } else {
  67. out <- TestResult{true, false}
  68. }
  69. return
  70. }
  71. // Check results of validation in "extensive" mode
  72. if len(res.Reasons) != tc.Failures {
  73. if res.AllowFailure {
  74. log.Printf("[%s] (%s harness) ignoring bad number of failures: %v", tc.Name, h.Name, res.Reasons)
  75. out <- TestResult{false, true}
  76. } else {
  77. log.Printf("[%s] (%s harness) expected %d failures, got %d:\n %v", tc.Name, h.Name, tc.Failures, len(res.Reasons), strings.Join(res.Reasons, "\n "))
  78. out <- TestResult{false, false}
  79. }
  80. return
  81. }
  82. out <- TestResult{true, false}
  83. }()
  84. }
  85. wg.Wait()
  86. return
  87. }