mirror of
https://github.com/protocolbuffers/protobuf-go.git
synced 2025-02-22 12:39:52 +00:00
integration_test: add conformance tests
Change-Id: I3c21e5069c34a6417c9177ae5f1bdcb801418c8a Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/173665 Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
This commit is contained in:
parent
06a6b0bda8
commit
d64dcebbc7
@ -36,8 +36,9 @@ var (
|
|||||||
purgeTimeout = 30 * 24 * time.Hour // 1 month
|
purgeTimeout = 30 * 24 * time.Hour // 1 month
|
||||||
|
|
||||||
// Variables initialized by mustInitDeps.
|
// Variables initialized by mustInitDeps.
|
||||||
goPath string
|
goPath string
|
||||||
modulePath string
|
modulePath string
|
||||||
|
protobufPath string
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test(t *testing.T) {
|
func Test(t *testing.T) {
|
||||||
@ -74,6 +75,13 @@ func Test(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
t.Run("ConformanceTests", func(t *testing.T) {
|
||||||
|
driverPath := filepath.Join("internal", "cmd", "conformance")
|
||||||
|
driver := filepath.Join(driverPath, "conformance.sh")
|
||||||
|
failureList := filepath.Join(driverPath, "failure_list_go.txt")
|
||||||
|
runner := filepath.Join(protobufPath, "conformance", "conformance-test-runner")
|
||||||
|
mustRunCommand(t, ".", runner, "--failure_list", failureList, "--enforce_recommended", driver)
|
||||||
|
})
|
||||||
t.Run("GeneratedGoFiles", func(t *testing.T) {
|
t.Run("GeneratedGoFiles", func(t *testing.T) {
|
||||||
diff := mustRunCommand(t, ".", "go", "run", "./internal/cmd/generate-types")
|
diff := mustRunCommand(t, ".", "go", "run", "./internal/cmd/generate-types")
|
||||||
if strings.TrimSpace(diff) != "" {
|
if strings.TrimSpace(diff) != "" {
|
||||||
@ -184,21 +192,22 @@ func mustInitDeps(t *testing.T) {
|
|||||||
// We avoid downloading the pre-compiled binaries since they do not contain
|
// We avoid downloading the pre-compiled binaries since they do not contain
|
||||||
// the conformance test runner.
|
// the conformance test runner.
|
||||||
workingDir = filepath.Join(testDir, "protobuf-"+protobufVersion)
|
workingDir = filepath.Join(testDir, "protobuf-"+protobufVersion)
|
||||||
if _, err := os.Stat(workingDir); err != nil {
|
protobufPath = workingDir
|
||||||
fmt.Printf("download %v\n", filepath.Base(workingDir))
|
if _, err := os.Stat(protobufPath); err != nil {
|
||||||
|
fmt.Printf("download %v\n", filepath.Base(protobufPath))
|
||||||
url := fmt.Sprintf("https://github.com/google/protobuf/releases/download/v%v/protobuf-all-%v.tar.gz", protobufVersion, protobufVersion)
|
url := fmt.Sprintf("https://github.com/google/protobuf/releases/download/v%v/protobuf-all-%v.tar.gz", protobufVersion, protobufVersion)
|
||||||
downloadArchive(check, workingDir, url, "protobuf-"+protobufVersion)
|
downloadArchive(check, protobufPath, url, "protobuf-"+protobufVersion)
|
||||||
|
|
||||||
fmt.Printf("build %v\n", filepath.Base(workingDir))
|
fmt.Printf("build %v\n", filepath.Base(protobufPath))
|
||||||
mustRunCommand(t, workingDir, "./autogen.sh")
|
mustRunCommand(t, protobufPath, "./autogen.sh")
|
||||||
mustRunCommand(t, workingDir, "./configure")
|
mustRunCommand(t, protobufPath, "./configure")
|
||||||
mustRunCommand(t, workingDir, "make")
|
mustRunCommand(t, protobufPath, "make")
|
||||||
mustRunCommand(t, filepath.Join(workingDir, "conformance"), "make")
|
mustRunCommand(t, filepath.Join(protobufPath, "conformance"), "make")
|
||||||
}
|
}
|
||||||
patchProtos(check, workingDir)
|
patchProtos(check, protobufPath)
|
||||||
check(os.Setenv("PROTOBUF_ROOT", workingDir)) // for generate-protos
|
check(os.Setenv("PROTOBUF_ROOT", protobufPath)) // for generate-protos
|
||||||
registerBinary("conform-test-runner", filepath.Join(workingDir, "conformance", "conformance-test-runner"))
|
registerBinary("conform-test-runner", filepath.Join(protobufPath, "conformance", "conformance-test-runner"))
|
||||||
registerBinary("protoc", filepath.Join(workingDir, "src", "protoc"))
|
registerBinary("protoc", filepath.Join(protobufPath, "src", "protoc"))
|
||||||
workingDir = ""
|
workingDir = ""
|
||||||
|
|
||||||
// Download each Go toolchain version.
|
// Download each Go toolchain version.
|
||||||
@ -281,19 +290,21 @@ func patchProtos(check func(error), repoRoot string) {
|
|||||||
javaPackageRx := regexp.MustCompile(`^option\s+java_package\s*=\s*".*"\s*;\s*$`)
|
javaPackageRx := regexp.MustCompile(`^option\s+java_package\s*=\s*".*"\s*;\s*$`)
|
||||||
goPackageRx := regexp.MustCompile(`^option\s+go_package\s*=\s*".*"\s*;\s*$`)
|
goPackageRx := regexp.MustCompile(`^option\s+go_package\s*=\s*".*"\s*;\s*$`)
|
||||||
files := map[string]string{
|
files := map[string]string{
|
||||||
"src/google/protobuf/any.proto": "github.com/golang/protobuf/v2/types/known;known_proto",
|
"src/google/protobuf/any.proto": "github.com/golang/protobuf/v2/types/known;known_proto",
|
||||||
"src/google/protobuf/api.proto": "github.com/golang/protobuf/v2/types/known;known_proto",
|
"src/google/protobuf/api.proto": "github.com/golang/protobuf/v2/types/known;known_proto",
|
||||||
"src/google/protobuf/duration.proto": "github.com/golang/protobuf/v2/types/known;known_proto",
|
"src/google/protobuf/duration.proto": "github.com/golang/protobuf/v2/types/known;known_proto",
|
||||||
"src/google/protobuf/empty.proto": "github.com/golang/protobuf/v2/types/known;known_proto",
|
"src/google/protobuf/empty.proto": "github.com/golang/protobuf/v2/types/known;known_proto",
|
||||||
"src/google/protobuf/field_mask.proto": "github.com/golang/protobuf/v2/types/known;known_proto",
|
"src/google/protobuf/field_mask.proto": "github.com/golang/protobuf/v2/types/known;known_proto",
|
||||||
"src/google/protobuf/source_context.proto": "github.com/golang/protobuf/v2/types/known;known_proto",
|
"src/google/protobuf/source_context.proto": "github.com/golang/protobuf/v2/types/known;known_proto",
|
||||||
"src/google/protobuf/struct.proto": "github.com/golang/protobuf/v2/types/known;known_proto",
|
"src/google/protobuf/struct.proto": "github.com/golang/protobuf/v2/types/known;known_proto",
|
||||||
"src/google/protobuf/timestamp.proto": "github.com/golang/protobuf/v2/types/known;known_proto",
|
"src/google/protobuf/timestamp.proto": "github.com/golang/protobuf/v2/types/known;known_proto",
|
||||||
"src/google/protobuf/type.proto": "github.com/golang/protobuf/v2/types/known;known_proto",
|
"src/google/protobuf/type.proto": "github.com/golang/protobuf/v2/types/known;known_proto",
|
||||||
"src/google/protobuf/wrappers.proto": "github.com/golang/protobuf/v2/types/known;known_proto",
|
"src/google/protobuf/wrappers.proto": "github.com/golang/protobuf/v2/types/known;known_proto",
|
||||||
"src/google/protobuf/descriptor.proto": "github.com/golang/protobuf/v2/types/descriptor;descriptor_proto",
|
"src/google/protobuf/descriptor.proto": "github.com/golang/protobuf/v2/types/descriptor;descriptor_proto",
|
||||||
"src/google/protobuf/compiler/plugin.proto": "github.com/golang/protobuf/v2/types/plugin;plugin_proto",
|
"src/google/protobuf/compiler/plugin.proto": "github.com/golang/protobuf/v2/types/plugin;plugin_proto",
|
||||||
"conformance/conformance.proto": "github.com/golang/protobuf/v2/internal/testprotos/conformance;conformance_proto",
|
"conformance/conformance.proto": "github.com/golang/protobuf/v2/internal/testprotos/conformance;conformance_proto",
|
||||||
|
"src/google/protobuf/test_messages_proto2.proto": "github.com/golang/protobuf/v2/internal/testprotos/conformance;conformance_proto",
|
||||||
|
"src/google/protobuf/test_messages_proto3.proto": "github.com/golang/protobuf/v2/internal/testprotos/conformance;conformance_proto",
|
||||||
}
|
}
|
||||||
for pbpath, gopath := range files {
|
for pbpath, gopath := range files {
|
||||||
b, err := ioutil.ReadFile(filepath.Join(repoRoot, pbpath))
|
b, err := ioutil.ReadFile(filepath.Join(repoRoot, pbpath))
|
||||||
|
8
internal/cmd/conformance/conformance.sh
Executable file
8
internal/cmd/conformance/conformance.sh
Executable file
@ -0,0 +1,8 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Copyright 2019 The Go Authors. All rights reserved.
|
||||||
|
# Use of this source code is governed by a BSD-style
|
||||||
|
# license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
cd $(dirname $0)
|
||||||
|
exec go run main.go $@
|
7
internal/cmd/conformance/failure_list_go.txt
Normal file
7
internal/cmd/conformance/failure_list_go.txt
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
Required.Proto3.JsonInput.IgnoreUnknownJsonFalse.ProtobufOutput
|
||||||
|
Required.Proto3.JsonInput.IgnoreUnknownJsonNull.ProtobufOutput
|
||||||
|
Required.Proto3.JsonInput.IgnoreUnknownJsonNumber.ProtobufOutput
|
||||||
|
Required.Proto3.JsonInput.IgnoreUnknownJsonObject.ProtobufOutput
|
||||||
|
Required.Proto3.JsonInput.IgnoreUnknownJsonString.ProtobufOutput
|
||||||
|
Required.Proto3.JsonInput.IgnoreUnknownJsonTrue.ProtobufOutput
|
||||||
|
Recommended.Proto3.JsonInput.FieldMaskInvalidCharacter
|
124
internal/cmd/conformance/main.go
Normal file
124
internal/cmd/conformance/main.go
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
// Copyright 2019 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// This binary implements the conformance test subprocess protocol as documented
|
||||||
|
// in conformance.proto.
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/golang/protobuf/v2/encoding/jsonpb"
|
||||||
|
"github.com/golang/protobuf/v2/proto"
|
||||||
|
|
||||||
|
pb "github.com/golang/protobuf/v2/internal/testprotos/conformance"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var sizeBuf [4]byte
|
||||||
|
inbuf := make([]byte, 0, 4096)
|
||||||
|
for {
|
||||||
|
_, err := io.ReadFull(os.Stdin, sizeBuf[:])
|
||||||
|
if err == io.EOF {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("conformance: read request: %v", err)
|
||||||
|
}
|
||||||
|
size := binary.LittleEndian.Uint32(sizeBuf[:])
|
||||||
|
if int(size) > cap(inbuf) {
|
||||||
|
inbuf = make([]byte, size)
|
||||||
|
}
|
||||||
|
inbuf = inbuf[:size]
|
||||||
|
if _, err := io.ReadFull(os.Stdin, inbuf); err != nil {
|
||||||
|
log.Fatalf("conformance: read request: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
req := &pb.ConformanceRequest{}
|
||||||
|
if err := proto.Unmarshal(inbuf, req); err != nil {
|
||||||
|
log.Fatalf("conformance: parse request: %v", err)
|
||||||
|
}
|
||||||
|
res := handle(req)
|
||||||
|
|
||||||
|
out, err := proto.Marshal(res)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("conformance: marshal response: %v", err)
|
||||||
|
}
|
||||||
|
binary.LittleEndian.PutUint32(sizeBuf[:], uint32(len(out)))
|
||||||
|
if _, err := os.Stdout.Write(sizeBuf[:]); err != nil {
|
||||||
|
log.Fatalf("conformance: write response: %v", err)
|
||||||
|
}
|
||||||
|
if _, err := os.Stdout.Write(out); err != nil {
|
||||||
|
log.Fatalf("conformance: write response: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func handle(req *pb.ConformanceRequest) *pb.ConformanceResponse {
|
||||||
|
var err error
|
||||||
|
var msg proto.Message = &pb.TestAllTypesProto2{}
|
||||||
|
if req.GetMessageType() == "protobuf_test_messages.proto3.TestAllTypesProto3" {
|
||||||
|
msg = &pb.TestAllTypesProto3{}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch p := req.Payload.(type) {
|
||||||
|
case *pb.ConformanceRequest_ProtobufPayload:
|
||||||
|
err = proto.Unmarshal(p.ProtobufPayload, msg)
|
||||||
|
case *pb.ConformanceRequest_JsonPayload:
|
||||||
|
err = jsonpb.Unmarshal(msg, []byte(p.JsonPayload))
|
||||||
|
default:
|
||||||
|
return &pb.ConformanceResponse{
|
||||||
|
Result: &pb.ConformanceResponse_RuntimeError{
|
||||||
|
RuntimeError: "unknown request payload type",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return &pb.ConformanceResponse{
|
||||||
|
Result: &pb.ConformanceResponse_ParseError{
|
||||||
|
ParseError: err.Error(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch req.RequestedOutputFormat {
|
||||||
|
case pb.WireFormat_PROTOBUF:
|
||||||
|
p, err := proto.Marshal(msg)
|
||||||
|
if err != nil {
|
||||||
|
return &pb.ConformanceResponse{
|
||||||
|
Result: &pb.ConformanceResponse_SerializeError{
|
||||||
|
SerializeError: err.Error(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &pb.ConformanceResponse{
|
||||||
|
Result: &pb.ConformanceResponse_ProtobufPayload{
|
||||||
|
ProtobufPayload: p,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
case pb.WireFormat_JSON:
|
||||||
|
p, err := jsonpb.Marshal(msg)
|
||||||
|
if err != nil {
|
||||||
|
return &pb.ConformanceResponse{
|
||||||
|
Result: &pb.ConformanceResponse_SerializeError{
|
||||||
|
SerializeError: err.Error(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &pb.ConformanceResponse{
|
||||||
|
Result: &pb.ConformanceResponse_JsonPayload{
|
||||||
|
JsonPayload: string(p),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return &pb.ConformanceResponse{
|
||||||
|
Result: &pb.ConformanceResponse_RuntimeError{
|
||||||
|
RuntimeError: "unknown output format",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -185,6 +185,8 @@ func generateRemoteProtos() {
|
|||||||
{"src", "google/protobuf/field_mask.proto"},
|
{"src", "google/protobuf/field_mask.proto"},
|
||||||
{"src", "google/protobuf/source_context.proto"},
|
{"src", "google/protobuf/source_context.proto"},
|
||||||
{"src", "google/protobuf/struct.proto"},
|
{"src", "google/protobuf/struct.proto"},
|
||||||
|
{"src", "google/protobuf/test_messages_proto2.proto"},
|
||||||
|
{"src", "google/protobuf/test_messages_proto3.proto"},
|
||||||
{"src", "google/protobuf/timestamp.proto"},
|
{"src", "google/protobuf/timestamp.proto"},
|
||||||
{"src", "google/protobuf/type.proto"},
|
{"src", "google/protobuf/type.proto"},
|
||||||
{"src", "google/protobuf/wrappers.proto"},
|
{"src", "google/protobuf/wrappers.proto"},
|
||||||
|
1915
internal/testprotos/conformance/test_messages_proto2.pb.go
Normal file
1915
internal/testprotos/conformance/test_messages_proto2.pb.go
Normal file
File diff suppressed because it is too large
Load Diff
2137
internal/testprotos/conformance/test_messages_proto3.pb.go
Normal file
2137
internal/testprotos/conformance/test_messages_proto3.pb.go
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user