...

Source file src/google.golang.org/protobuf/internal/conformance/conformance_test.go

Documentation: google.golang.org/protobuf/internal/conformance

     1  // Copyright 2019 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package conformance_test
     6  
     7  import (
     8  	"encoding/binary"
     9  	"flag"
    10  	"fmt"
    11  	"io"
    12  	"log"
    13  	"os"
    14  	"os/exec"
    15  	"path/filepath"
    16  	"testing"
    17  
    18  	"google.golang.org/protobuf/encoding/protojson"
    19  	"google.golang.org/protobuf/encoding/prototext"
    20  	"google.golang.org/protobuf/proto"
    21  
    22  	pb "google.golang.org/protobuf/internal/testprotos/conformance"
    23  	epb "google.golang.org/protobuf/internal/testprotos/conformance/editions"
    24  	empb "google.golang.org/protobuf/internal/testprotos/conformance/editionsmigration"
    25  )
    26  
    27  func init() {
    28  	// When the environment variable RUN_AS_CONFORMANCE_PLUGIN is set,
    29  	// we skip running the tests and instead act as a conformance plugin.
    30  	// This allows the binary to pass itself to conformance.
    31  	if os.Getenv("RUN_AS_CONFORMANCE_PLUGIN") == "1" {
    32  		main()
    33  		os.Exit(0)
    34  	}
    35  }
    36  
    37  var (
    38  	execute   = flag.Bool("execute", false, "execute the conformance test")
    39  	protoRoot = flag.String("protoroot", os.Getenv("PROTOBUF_ROOT"), "The root of the protobuf source tree.")
    40  )
    41  
    42  func Test(t *testing.T) {
    43  	if !*execute {
    44  		t.SkipNow()
    45  	}
    46  	binPath := filepath.Join(*protoRoot, "bazel-bin", "conformance", "conformance_test_runner")
    47  	cmd := exec.Command(binPath,
    48  		"--failure_list", "failing_tests.txt",
    49  		"--text_format_failure_list", "failing_tests_text_format.txt",
    50  		"--enforce_recommended",
    51  		"--maximum_edition", "2023",
    52  		os.Args[0])
    53  	cmd.Env = append(os.Environ(), "RUN_AS_CONFORMANCE_PLUGIN=1")
    54  	out, err := cmd.CombinedOutput()
    55  	if err != nil {
    56  		t.Fatalf("execution error: %v\n\n%s", err, out)
    57  	}
    58  }
    59  
    60  func main() {
    61  	var sizeBuf [4]byte
    62  	inbuf := make([]byte, 0, 4096)
    63  	for {
    64  		_, err := io.ReadFull(os.Stdin, sizeBuf[:])
    65  		if err == io.EOF {
    66  			break
    67  		}
    68  		if err != nil {
    69  			log.Fatalf("conformance: read request: %v", err)
    70  		}
    71  		size := binary.LittleEndian.Uint32(sizeBuf[:])
    72  		if int(size) > cap(inbuf) {
    73  			inbuf = make([]byte, size)
    74  		}
    75  		inbuf = inbuf[:size]
    76  		if _, err := io.ReadFull(os.Stdin, inbuf); err != nil {
    77  			log.Fatalf("conformance: read request: %v", err)
    78  		}
    79  
    80  		req := &pb.ConformanceRequest{}
    81  		if err := proto.Unmarshal(inbuf, req); err != nil {
    82  			log.Fatalf("conformance: parse request: %v", err)
    83  		}
    84  		res := handle(req)
    85  
    86  		out, err := proto.Marshal(res)
    87  		if err != nil {
    88  			log.Fatalf("conformance: marshal response: %v", err)
    89  		}
    90  		binary.LittleEndian.PutUint32(sizeBuf[:], uint32(len(out)))
    91  		if _, err := os.Stdout.Write(sizeBuf[:]); err != nil {
    92  			log.Fatalf("conformance: write response: %v", err)
    93  		}
    94  		if _, err := os.Stdout.Write(out); err != nil {
    95  			log.Fatalf("conformance: write response: %v", err)
    96  		}
    97  	}
    98  }
    99  
   100  func handle(req *pb.ConformanceRequest) (res *pb.ConformanceResponse) {
   101  	var msg proto.Message = &pb.TestAllTypesProto2{}
   102  	switch req.GetMessageType() {
   103  	case "protobuf_test_messages.proto3.TestAllTypesProto3":
   104  		msg = &pb.TestAllTypesProto3{}
   105  	case "protobuf_test_messages.proto2.TestAllTypesProto2":
   106  		msg = &pb.TestAllTypesProto2{}
   107  	case "protobuf_test_messages.editions.TestAllTypesEdition2023":
   108  		msg = &epb.TestAllTypesEdition2023{}
   109  	case "protobuf_test_messages.editions.proto3.TestAllTypesProto3":
   110  		msg = &empb.TestAllTypesProto3{}
   111  	case "protobuf_test_messages.editions.proto2.TestAllTypesProto2":
   112  		msg = &empb.TestAllTypesProto2{}
   113  	default:
   114  		panic(fmt.Sprintf("unknown message type: %s", req.GetMessageType()))
   115  	}
   116  
   117  	// Unmarshal the test message.
   118  	var err error
   119  	switch p := req.Payload.(type) {
   120  	case *pb.ConformanceRequest_ProtobufPayload:
   121  		err = proto.Unmarshal(p.ProtobufPayload, msg)
   122  	case *pb.ConformanceRequest_JsonPayload:
   123  		err = protojson.UnmarshalOptions{
   124  			DiscardUnknown: req.TestCategory == pb.TestCategory_JSON_IGNORE_UNKNOWN_PARSING_TEST,
   125  		}.Unmarshal([]byte(p.JsonPayload), msg)
   126  	case *pb.ConformanceRequest_TextPayload:
   127  		err = prototext.Unmarshal([]byte(p.TextPayload), msg)
   128  	default:
   129  		return &pb.ConformanceResponse{
   130  			Result: &pb.ConformanceResponse_RuntimeError{
   131  				RuntimeError: "unknown request payload type",
   132  			},
   133  		}
   134  	}
   135  	if err != nil {
   136  		return &pb.ConformanceResponse{
   137  			Result: &pb.ConformanceResponse_ParseError{
   138  				ParseError: err.Error(),
   139  			},
   140  		}
   141  	}
   142  
   143  	// Marshal the test message.
   144  	var b []byte
   145  	switch req.RequestedOutputFormat {
   146  	case pb.WireFormat_PROTOBUF:
   147  		b, err = proto.Marshal(msg)
   148  		res = &pb.ConformanceResponse{
   149  			Result: &pb.ConformanceResponse_ProtobufPayload{
   150  				ProtobufPayload: b,
   151  			},
   152  		}
   153  	case pb.WireFormat_JSON:
   154  		b, err = protojson.Marshal(msg)
   155  		res = &pb.ConformanceResponse{
   156  			Result: &pb.ConformanceResponse_JsonPayload{
   157  				JsonPayload: string(b),
   158  			},
   159  		}
   160  	case pb.WireFormat_TEXT_FORMAT:
   161  		b, err = prototext.MarshalOptions{
   162  			EmitUnknown: req.PrintUnknownFields,
   163  		}.Marshal(msg)
   164  		res = &pb.ConformanceResponse{
   165  			Result: &pb.ConformanceResponse_TextPayload{
   166  				TextPayload: string(b),
   167  			},
   168  		}
   169  	default:
   170  		return &pb.ConformanceResponse{
   171  			Result: &pb.ConformanceResponse_RuntimeError{
   172  				RuntimeError: "unknown output format",
   173  			},
   174  		}
   175  	}
   176  	if err != nil {
   177  		return &pb.ConformanceResponse{
   178  			Result: &pb.ConformanceResponse_SerializeError{
   179  				SerializeError: err.Error(),
   180  			},
   181  		}
   182  	}
   183  	return res
   184  }
   185  

View as plain text