123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- package main
- import (
- "fmt"
- "io/ioutil"
- "log"
- "os"
- "github.com/envoyproxy/protoc-gen-validate/tests/harness/cases/go"
- _ "github.com/envoyproxy/protoc-gen-validate/tests/harness/cases/go"
- _ "github.com/envoyproxy/protoc-gen-validate/tests/harness/cases/other_package/go"
- "github.com/envoyproxy/protoc-gen-validate/tests/harness/go"
- "google.golang.org/protobuf/proto"
- )
- func main() {
- b, err := ioutil.ReadAll(os.Stdin)
- checkErr(err)
- tc := new(harness.TestCase)
- checkErr(proto.Unmarshal(b, tc))
- msg, err := tc.Message.UnmarshalNew()
- checkErr(err)
- _, isIgnored := msg.(*cases.MessageIgnored)
- vMsg, hasValidate := msg.(interface {
- Validate() error
- })
- vAllMsg, hasValidateAll := msg.(interface {
- ValidateAll() error
- })
- var multierr error
- if isIgnored {
- // confirm that ignored messages don't have a validate method
- if hasValidate {
- checkErr(fmt.Errorf("ignored message %T has Validate() method", msg))
- }
- if hasValidateAll {
- checkErr(fmt.Errorf("ignored message %T has ValidateAll() method", msg))
- }
- } else if !hasValidate {
- checkErr(fmt.Errorf("non-ignored message %T is missing Validate()", msg))
- } else if !hasValidateAll {
- checkErr(fmt.Errorf("non-ignored message %T is missing ValidateAll()", msg))
- } else {
- err = vMsg.Validate()
- multierr = vAllMsg.ValidateAll()
- }
- checkValid(err, multierr)
- }
- type hasAllErrors interface{ AllErrors() []error }
- type hasCause interface{ Cause() error }
- func checkValid(err, multierr error) {
- if err == nil && multierr == nil {
- resp(&harness.TestResult{Valid: true})
- return
- }
- if (err != nil) != (multierr != nil) {
- checkErr(fmt.Errorf("different verdict of Validate() [%v] vs. ValidateAll() [%v]", err, multierr))
- return
- }
- // Extract the message from "lazy" Validate(), for comparison with ValidateAll()
- rootCause := err
- for {
- caused, ok := rootCause.(hasCause)
- if !ok || caused.Cause() == nil {
- break
- }
- rootCause = caused.Cause()
- }
- // Retrieve the messages from "extensive" ValidateAll() and compare first one with the "lazy" message
- m, ok := multierr.(hasAllErrors)
- if !ok {
- checkErr(fmt.Errorf("ValidateAll() returned error without AllErrors() method: %#v", multierr))
- return
- }
- reasons := mergeReasons(nil, m)
- if rootCause.Error() != reasons[0] {
- checkErr(fmt.Errorf("different first message, Validate()==%q, ValidateAll()==%q", rootCause.Error(), reasons[0]))
- return
- }
- resp(&harness.TestResult{Reasons: reasons})
- }
- func mergeReasons(reasons []string, multi hasAllErrors) []string {
- for _, err := range multi.AllErrors() {
- caused, ok := err.(hasCause)
- if ok && caused.Cause() != nil {
- err = caused.Cause()
- }
- multi, ok := err.(hasAllErrors)
- if ok {
- reasons = mergeReasons(reasons, multi)
- } else {
- reasons = append(reasons, err.Error())
- }
- }
- return reasons
- }
- func checkErr(err error) {
- if err == nil {
- return
- }
- resp(&harness.TestResult{
- Error: true,
- Reasons: []string{err.Error()},
- })
- }
- func resp(result *harness.TestResult) {
- if b, err := proto.Marshal(result); err != nil {
- log.Fatalf("could not marshal response: %v", err)
- } else if _, err = os.Stdout.Write(b); err != nil {
- log.Fatalf("could not write response: %v", err)
- }
- os.Exit(0)
- }
|