ADD: added new version of protobuf

This commit is contained in:
Henry Winkel
2022-12-20 10:09:28 +01:00
parent 4a79559129
commit 1e2b3dda7b
1513 changed files with 123720 additions and 83381 deletions

View File

@@ -1,8 +1,6 @@
# Conformance testing for Protobuf.
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library", "cc_proto_library", "objc_library")
load("//:protobuf.bzl", "internal_csharp_proto_library", "internal_objc_proto_library", "internal_php_proto_library", "internal_py_proto_library", "internal_ruby_proto_library")
load("//build_defs:internal_shell.bzl", "inline_sh_binary")
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library", "cc_proto_library")
load(
"@rules_pkg//:mappings.bzl",
"pkg_attributes",
@@ -12,38 +10,21 @@ load(
)
exports_files([
"bazel_conformance_test_runner.sh",
"failure_list_cpp.txt",
"failure_list_csharp.txt",
"conformance_test_runner.sh",
"failure_list_java.txt",
"failure_list_java_lite.txt",
"failure_list_objc.txt",
"failure_list_php.txt",
"failure_list_php_c.txt",
"failure_list_python.txt",
"failure_list_python_cpp.txt",
"failure_list_ruby.txt",
"failure_list_jruby.txt",
"text_format_failure_list_cpp.txt",
"text_format_failure_list_csharp.txt",
"text_format_failure_list_java.txt",
"text_format_failure_list_java_lite.txt",
"text_format_failure_list_php.txt",
"text_format_failure_list_php_c.txt",
"text_format_failure_list_python.txt",
"text_format_failure_list_python_cpp.txt",
"text_format_failure_list_ruby.txt",
"text_format_failure_list_jruby.txt",
])
cc_proto_library(
name = "test_messages_proto2_proto_cc",
deps = ["//src/google/protobuf:test_messages_proto2_proto"],
deps = ["//:test_messages_proto2_proto"],
)
cc_proto_library(
name = "test_messages_proto3_proto_cc",
deps = ["//src/google/protobuf:test_messages_proto3_proto"],
deps = ["//:test_messages_proto3_proto"],
)
proto_library(
@@ -53,18 +34,10 @@ proto_library(
)
cc_proto_library(
name = "conformance_cc_proto",
name = "conformance_proto_cc",
deps = [":conformance_proto"],
)
internal_csharp_proto_library(
name = "conformance_csharp_proto",
srcs = ["conformance.proto"],
visibility = [
"//csharp:__subpackages__",
],
)
java_proto_library(
name = "conformance_java_proto",
visibility = [
@@ -81,49 +54,11 @@ java_lite_proto_library(
deps = [":conformance_proto"],
)
internal_objc_proto_library(
name = "conformance_objc_proto",
srcs = ["conformance.proto"],
visibility = [
"//conformance:__pkg__",
"//objc:__pkg__",
],
)
internal_py_proto_library(
name = "conformance_py_proto",
srcs = ["conformance.proto"],
srcs_version = "PY2AND3",
visibility = [
"//python:__subpackages__",
],
)
internal_php_proto_library(
name = "conformance_php_proto",
srcs = ["conformance.proto"],
outs = [
"Conformance/ConformanceRequest.php",
"Conformance/ConformanceResponse.php",
"Conformance/FailureSet.php",
"Conformance/JspbEncodingConfig.php",
"Conformance/TestCategory.php",
"Conformance/WireFormat.php",
"GPBMetadata/Conformance.php",
],
visibility = [
"//conformance:__pkg__",
"//php:__pkg__",
],
)
internal_ruby_proto_library(
name = "conformance_ruby_proto",
srcs = ["conformance.proto"],
visibility = [
"//conformance:__pkg__",
"//ruby:__pkg__",
],
cc_library(
name = "jsoncpp",
srcs = ["third_party/jsoncpp/jsoncpp.cpp"],
hdrs = ["third_party/jsoncpp/json.h"],
includes = ["."],
)
cc_library(
@@ -136,11 +71,7 @@ cc_library(
"conformance_test.h",
],
includes = ["."],
deps = [
":conformance_cc_proto",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/strings:str_format",
],
deps = [":conformance_proto_cc"],
)
cc_library(
@@ -149,10 +80,9 @@ cc_library(
hdrs = ["binary_json_conformance_suite.h"],
deps = [
":conformance_test",
"@jsoncpp//:jsoncpp",
":jsoncpp",
":test_messages_proto2_proto_cc",
":test_messages_proto3_proto_cc",
"@com_google_absl//absl/status",
],
)
@@ -175,28 +105,11 @@ cc_binary(
":binary_json_conformance_suite",
":conformance_test",
":text_format_conformance_suite",
"@com_google_absl//absl/strings:str_format",
],
)
cc_binary(
name = "conformance_cpp",
testonly = 1,
srcs = ["conformance_cpp.cc"],
visibility = ["//src:__subpackages__"],
deps = [
":conformance_cc_proto",
"//:protobuf",
"//:test_messages_proto2_cc_proto",
"//:test_messages_proto3_cc_proto",
"@com_google_absl//absl/status",
"@com_google_absl//absl/status:statusor",
],
)
java_binary(
name = "conformance_java",
testonly = 1,
srcs = ["ConformanceJava.java"],
main_class = "ConformanceJava",
visibility = [
@@ -213,7 +126,6 @@ java_binary(
java_binary(
name = "conformance_java_lite",
testonly = 1,
srcs = ["ConformanceJavaLite.java"],
main_class = "ConformanceJavaLite",
visibility = [
@@ -228,119 +140,10 @@ java_binary(
],
)
py_binary(
name = "conformance_python",
testonly = 1,
srcs = ["conformance_python.py"],
imports = [
"..",
"../python",
],
srcs_version = "PY2AND3",
visibility = ["//python:__subpackages__"],
deps = [
":conformance_py_proto",
"//:protobuf_python",
"//python:test_messages_proto2_py_proto",
"//python:test_messages_proto3_py_proto",
],
)
inline_sh_binary(
name = "conformance_php",
testonly = 1,
srcs = [
"autoload.php",
"conformance_php.php",
],
cmd = """
php -d include_path=conformance:src/google/protobuf \\
-d auto_prepend_file=$(rootpath autoload.php) \\
$(rootpath conformance_php.php)
""",
visibility = ["//php:__subpackages__"],
deps = [
":conformance_php_proto",
"//:test_messages_proto3_php_proto",
"//php:source_files",
],
)
inline_sh_binary(
name = "conformance_php_c",
testonly = 1,
srcs = [
"conformance_php.php",
"//php:extension",
],
cmd = """
php -dextension=$(rootpath //php:extension) \\
-d include_path=conformance:src/google/protobuf \\
$(rootpath conformance_php.php)
""",
visibility = ["//php:__subpackages__"],
deps = [
":conformance_php_proto",
"//:test_messages_proto3_php_proto",
],
)
inline_sh_binary(
name = "conformance_csharp",
testonly = 1,
srcs = ["//csharp/src/Google.Protobuf.Conformance:conformance_dll"],
cmd = "dotnet $(rootpath //csharp/src/Google.Protobuf.Conformance:conformance_dll)",
visibility = ["//csharp:__subpackages__"],
deps = [
"//csharp/src/Google.Protobuf.Conformance:conformance_runfiles",
],
)
objc_library(
name = "conformance_objc_lib",
testonly = 1,
non_arc_srcs = ["conformance_objc.m"],
# See https://github.com/bazelbuild/bazel/issues/12897.
tags = ["manual"],
deps = [
":conformance_objc_proto",
"//:test_messages_proto2_objc_proto",
"//:test_messages_proto3_objc_proto",
],
)
cc_binary(
name = "conformance_objc",
testonly = 1,
# See https://github.com/bazelbuild/bazel/issues/12897.
tags = ["manual"],
visibility = ["//objectivec:__subpackages__"],
deps = [":conformance_objc_lib"],
)
inline_sh_binary(
name = "conformance_ruby",
testonly = 1,
srcs = ["conformance_ruby.rb"],
cmd = "RUBYLIB=ruby/lib:conformance:src $(rootpath conformance_ruby.rb)",
visibility = ["//ruby:__subpackages__"],
deps = [
":conformance_ruby_proto",
"//:test_messages_proto2_ruby_proto",
"//:test_messages_proto3_ruby_proto",
"//:well_known_ruby_protos",
"//ruby:protobuf",
],
)
################################################################################
# Distribution files
################################################################################
filegroup(
name = "all_files",
srcs = glob(["**/*"]),
visibility = ["//src/google/protobuf/compiler/csharp:__pkg__"],
visibility = ["//:__pkg__"],
)
pkg_files(
@@ -349,10 +152,11 @@ pkg_files(
["**/*"],
exclude = [
# Handled by dist_scripts:
"bazel_conformance_test_runner.sh",
"conformance_test_runner.sh",
# The following are not in autotools dist:
"autoload.php",
"conformance_nodejs.js",
"failure_list_jruby.txt",
"update_failure_list.py",
],
@@ -361,10 +165,19 @@ pkg_files(
visibility = ["//pkg:__pkg__"],
)
pkg_files(
name = "dist_scripts",
srcs = ["conformance_test_runner.sh"],
attributes = pkg_attributes(mode = "0555"),
strip_prefix = strip_prefix.from_root(""),
visibility = ["//pkg:__pkg__"],
)
pkg_filegroup(
name = "all_dist_files",
srcs = [
":dist_files",
":dist_scripts",
],
visibility = ["//pkg:__pkg__"],
)

View File

@@ -0,0 +1,372 @@
## Process this file with automake to produce Makefile.in
conformance_protoc_inputs = \
conformance.proto \
$(top_srcdir)/src/google/protobuf/test_messages_proto3.proto
# proto2 input files, should be separated with proto3, as we
# can't generate proto2 files for php.
conformance_proto2_protoc_inputs = \
$(top_srcdir)/src/google/protobuf/test_messages_proto2.proto
well_known_type_protoc_inputs = \
$(top_srcdir)/src/google/protobuf/any.proto \
$(top_srcdir)/src/google/protobuf/duration.proto \
$(top_srcdir)/src/google/protobuf/field_mask.proto \
$(top_srcdir)/src/google/protobuf/struct.proto \
$(top_srcdir)/src/google/protobuf/timestamp.proto \
$(top_srcdir)/src/google/protobuf/wrappers.proto
protoc_outputs = \
conformance.pb.cc \
conformance.pb.h
other_language_protoc_outputs = \
conformance_pb2.py \
Conformance.pbobjc.h \
Conformance.pbobjc.m \
conformance_pb.js \
conformance_pb.rb \
com/google/protobuf/Any.java \
com/google/protobuf/AnyOrBuilder.java \
com/google/protobuf/AnyProto.java \
com/google/protobuf/BoolValue.java \
com/google/protobuf/BoolValueOrBuilder.java \
com/google/protobuf/BytesValue.java \
com/google/protobuf/BytesValueOrBuilder.java \
com/google/protobuf/conformance/Conformance.java \
com/google/protobuf/DoubleValue.java \
com/google/protobuf/DoubleValueOrBuilder.java \
com/google/protobuf/Duration.java \
com/google/protobuf/DurationOrBuilder.java \
com/google/protobuf/DurationProto.java \
com/google/protobuf/FieldMask.java \
com/google/protobuf/FieldMaskOrBuilder.java \
com/google/protobuf/FieldMaskProto.java \
com/google/protobuf/FloatValue.java \
com/google/protobuf/FloatValueOrBuilder.java \
com/google/protobuf/Int32Value.java \
com/google/protobuf/Int32ValueOrBuilder.java \
com/google/protobuf/Int64Value.java \
com/google/protobuf/Int64ValueOrBuilder.java \
com/google/protobuf/ListValue.java \
com/google/protobuf/ListValueOrBuilder.java \
com/google/protobuf/NullValue.java \
com/google/protobuf/StringValue.java \
com/google/protobuf/StringValueOrBuilder.java \
com/google/protobuf/Struct.java \
com/google/protobuf/StructOrBuilder.java \
com/google/protobuf/StructProto.java \
com/google/protobuf/Timestamp.java \
com/google/protobuf/TimestampOrBuilder.java \
com/google/protobuf/TimestampProto.java \
com/google/protobuf/UInt32Value.java \
com/google/protobuf/UInt32ValueOrBuilder.java \
com/google/protobuf/UInt64Value.java \
com/google/protobuf/UInt64ValueOrBuilder.java \
com/google/protobuf/Value.java \
com/google/protobuf/ValueOrBuilder.java \
com/google/protobuf/WrappersProto.java \
com/google/protobuf_test_messages/proto3/TestMessagesProto3.java \
com/google/protobuf_test_messages/proto2/TestMessagesProto2.java \
google/protobuf/any.pb.cc \
google/protobuf/any.pb.h \
google/protobuf/any.rb \
google/protobuf/any_pb2.py \
google/protobuf/duration.pb.cc \
google/protobuf/duration.pb.h \
google/protobuf/duration.rb \
google/protobuf/duration_pb2.py \
google/protobuf/field_mask.pb.cc \
google/protobuf/field_mask.pb.h \
google/protobuf/field_mask.rb \
google/protobuf/field_mask_pb2.py \
google/protobuf/struct.pb.cc \
google/protobuf/struct.pb.h \
google/protobuf/struct.rb \
google/protobuf/struct_pb2.py \
google/protobuf/TestMessagesProto2.pbobjc.h \
google/protobuf/TestMessagesProto2.pbobjc.m \
google/protobuf/TestMessagesProto3.pbobjc.h \
google/protobuf/TestMessagesProto3.pbobjc.m \
google/protobuf/test_messages_proto3.pb.cc \
google/protobuf/test_messages_proto3.pb.h \
google/protobuf/test_messages_proto2.pb.cc \
google/protobuf/test_messages_proto2.pb.h \
google/protobuf/test_messages_proto3_pb.rb \
google/protobuf/test_messages_proto3_pb2.py \
google/protobuf/test_messages_proto2_pb2.py \
google/protobuf/timestamp.pb.cc \
google/protobuf/timestamp.pb.h \
google/protobuf/timestamp.rb \
google/protobuf/timestamp_pb2.py \
google/protobuf/wrappers.pb.cc \
google/protobuf/wrappers.pb.h \
google/protobuf/wrappers.rb \
google/protobuf/wrappers_pb2.py \
Conformance/ConformanceRequest.php \
Conformance/ConformanceResponse.php \
Conformance/FailureSet.php \
Conformance/WireFormat.php \
GPBMetadata/Conformance.php \
GPBMetadata/Google/Protobuf/Any.php \
GPBMetadata/Google/Protobuf/Duration.php \
GPBMetadata/Google/Protobuf/FieldMask.php \
GPBMetadata/Google/Protobuf/Struct.php \
GPBMetadata/Google/Protobuf/TestMessagesProto3.php \
GPBMetadata/Google/Protobuf/Timestamp.php \
GPBMetadata/Google/Protobuf/Wrappers.php \
Google/Protobuf/Any.php \
Google/Protobuf/BoolValue.php \
Google/Protobuf/BytesValue.php \
Google/Protobuf/DoubleValue.php \
Google/Protobuf/Duration.php \
Google/Protobuf/FieldMask.php \
Google/Protobuf/FloatValue.php \
Google/Protobuf/Int32Value.php \
Google/Protobuf/Int64Value.php \
Google/Protobuf/ListValue.php \
Google/Protobuf/NullValue.php \
Google/Protobuf/StringValue.php \
Google/Protobuf/Struct.php \
Google/Protobuf/Timestamp.php \
Google/Protobuf/UInt32Value.php \
Google/Protobuf/UInt64Value.php \
Google/Protobuf/Value.php \
Protobuf_test_messages/Proto3/ForeignEnum.php \
Protobuf_test_messages/Proto3/ForeignMessage.php \
Protobuf_test_messages/Proto3/TestAllTypes_NestedEnum.php \
Protobuf_test_messages/Proto3/TestAllTypes_NestedMessage.php \
Protobuf_test_messages/Proto3/TestAllTypes.php
# lite/com/google/protobuf/Any.java \
# lite/com/google/protobuf/AnyOrBuilder.java \
# lite/com/google/protobuf/AnyProto.java \
# lite/com/google/protobuf/BoolValue.java \
# lite/com/google/protobuf/BoolValueOrBuilder.java \
# lite/com/google/protobuf/BytesValue.java \
# lite/com/google/protobuf/BytesValueOrBuilder.java \
# lite/com/google/protobuf/conformance/Conformance.java \
# lite/com/google/protobuf/DoubleValue.java \
# lite/com/google/protobuf/DoubleValueOrBuilder.java \
# lite/com/google/protobuf/Duration.java \
# lite/com/google/protobuf/DurationOrBuilder.java \
# lite/com/google/protobuf/DurationProto.java \
# lite/com/google/protobuf/FieldMask.java \
# lite/com/google/protobuf/FieldMaskOrBuilder.java \
# lite/com/google/protobuf/FieldMaskProto.java \
# lite/com/google/protobuf/FloatValue.java \
# lite/com/google/protobuf/FloatValueOrBuilder.java \
# lite/com/google/protobuf/Int32Value.java \
# lite/com/google/protobuf/Int32ValueOrBuilder.java \
# lite/com/google/protobuf/Int64Value.java \
# lite/com/google/protobuf/Int64ValueOrBuilder.java \
# lite/com/google/protobuf/ListValue.java \
# lite/com/google/protobuf/ListValueOrBuilder.java \
# lite/com/google/protobuf/NullValue.java \
# lite/com/google/protobuf/StringValue.java \
# lite/com/google/protobuf/StringValueOrBuilder.java \
# lite/com/google/protobuf/Struct.java \
# lite/com/google/protobuf/StructOrBuilder.java \
# lite/com/google/protobuf/StructProto.java \
# lite/com/google/protobuf/Timestamp.java \
# lite/com/google/protobuf/TimestampOrBuilder.java \
# lite/com/google/protobuf/TimestampProto.java \
# lite/com/google/protobuf/UInt32Value.java \
# lite/com/google/protobuf/UInt32ValueOrBuilder.java \
# lite/com/google/protobuf/UInt64Value.java \
# lite/com/google/protobuf/UInt64ValueOrBuilder.java \
# lite/com/google/protobuf/Value.java \
# lite/com/google/protobuf/ValueOrBuilder.java \
# lite/com/google/protobuf/WrappersProto.java
bin_PROGRAMS = conformance-test-runner conformance-cpp
# All source files excepet C++/Objective-C ones should be explicitly listed
# here because the autoconf tools don't include files of other languages
# automatically.
EXTRA_DIST = \
ConformanceJava.java \
ConformanceJavaLite.java \
README.md \
conformance.proto \
conformance_python.py \
conformance_ruby.rb \
conformance_php.php \
failure_list_cpp.txt \
failure_list_csharp.txt \
failure_list_java.txt \
failure_list_js.txt \
failure_list_objc.txt \
failure_list_python.txt \
failure_list_python_cpp.txt \
failure_list_python-post26.txt \
failure_list_ruby.txt \
failure_list_php.txt \
failure_list_php_c.txt
conformance_test_runner_LDADD = $(top_srcdir)/src/libprotobuf.la
conformance_test_runner_SOURCES = conformance_test.h conformance_test.cc \
conformance_test_main.cc \
binary_json_conformance_suite.h \
binary_json_conformance_suite.cc \
text_format_conformance_suite.h \
text_format_conformance_suite.cc \
conformance_test_runner.cc \
third_party/jsoncpp/json.h \
third_party/jsoncpp/jsoncpp.cpp
nodist_conformance_test_runner_SOURCES = conformance.pb.cc google/protobuf/test_messages_proto3.pb.cc google/protobuf/test_messages_proto2.pb.cc
conformance_test_runner_CPPFLAGS = -I$(top_srcdir)/src -I$(srcdir)
conformance_test_runner_CXXFLAGS = -std=c++11
# Explicit deps because BUILT_SOURCES are only done before a "make all/check"
# so a direct "make test_cpp" could fail if parallel enough.
conformance_test_runner-conformance_test.$(OBJEXT): conformance.pb.h
conformance_test_runner-conformance_test_runner.$(OBJEXT): conformance.pb.h
conformance_cpp_LDADD = $(top_srcdir)/src/libprotobuf.la
conformance_cpp_SOURCES = conformance_cpp.cc
nodist_conformance_cpp_SOURCES = conformance.pb.cc google/protobuf/test_messages_proto3.pb.cc google/protobuf/test_messages_proto2.pb.cc
conformance_cpp_CPPFLAGS = -I$(top_srcdir)/src
# Explicit dep because BUILT_SOURCES are only done before a "make all/check"
# so a direct "make test_cpp" could fail if parallel enough.
conformance_cpp-conformance_cpp.$(OBJEXT): conformance.pb.h
if OBJC_CONFORMANCE_TEST
bin_PROGRAMS += conformance-objc
conformance_objc_SOURCES = conformance_objc.m ../objectivec/GPBProtocolBuffers.m
nodist_conformance_objc_SOURCES = Conformance.pbobjc.m google/protobuf/TestMessagesProto2.pbobjc.m google/protobuf/TestMessagesProto3.pbobjc.m
# On travis, the build fails without the isysroot because whatever system
# headers are being found don't include generics support for
# NSArray/NSDictionary, the only guess is their image at one time had an odd
# setup for Xcode and old frameworks are being found.
conformance_objc_CPPFLAGS = -I$(top_srcdir)/objectivec -isysroot `xcrun --sdk macosx --show-sdk-path`
conformance_objc_LDFLAGS = -framework Foundation
# Explicit dep because BUILT_SOURCES are only done before a "make all/check"
# so a direct "make test_objc" could fail if parallel enough.
conformance_objc-conformance_objc.$(OBJEXT): Conformance.pbobjc.h google/protobuf/TestMessagesProto2.pbobjc.h google/protobuf/TestMessagesProto3.pbobjc.h
endif
# JavaScript well-known types are expected to be in a directory called
# google-protobuf, because they are usually in the google-protobuf npm
# package. But we want to use the sources from our tree, so we recreate
# that directory structure here.
google-protobuf:
mkdir google-protobuf
if USE_EXTERNAL_PROTOC
# Some implementations include pre-generated versions of well-known types.
protoc_middleman: $(conformance_protoc_inputs) $(conformance_proto2_protoc_inputs) $(well_known_type_protoc_inputs) google-protobuf
$(PROTOC) -I$(srcdir) -I$(top_srcdir) --cpp_out=. --java_out=. --ruby_out=. --objc_out=. --python_out=. --php_out=. $(conformance_protoc_inputs)
$(PROTOC) -I$(srcdir) -I$(top_srcdir) --cpp_out=. --java_out=. --ruby_out=. --objc_out=. --python_out=. $(conformance_proto2_protoc_inputs)
$(PROTOC) -I$(srcdir) -I$(top_srcdir) --cpp_out=. --java_out=. --ruby_out=. --python_out=. $(well_known_type_protoc_inputs)
## $(PROTOC) -I$(srcdir) -I$(top_srcdir) --java_out=lite:lite $(conformance_protoc_inputs) $(well_known_type_protoc_inputs)
touch protoc_middleman
else
# We have to cd to $(srcdir) before executing protoc because $(protoc_inputs) is
# relative to srcdir, which may not be the same as the current directory when
# building out-of-tree.
protoc_middleman: $(top_srcdir)/src/protoc$(EXEEXT) $(conformance_protoc_inputs) $(conformance_proto2_protoc_inputs) $(well_known_type_protoc_inputs) google-protobuf
oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --cpp_out=$$oldpwd --java_out=$$oldpwd --ruby_out=$$oldpwd --objc_out=$$oldpwd --python_out=$$oldpwd --php_out=$$oldpwd $(conformance_protoc_inputs) )
oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --cpp_out=$$oldpwd --java_out=$$oldpwd --ruby_out=$$oldpwd --objc_out=$$oldpwd --python_out=$$oldpwd $(conformance_proto2_protoc_inputs) )
oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --cpp_out=$$oldpwd --java_out=$$oldpwd --ruby_out=$$oldpwd --python_out=$$oldpwd $(well_known_type_protoc_inputs) )
## @mkdir -p lite
## oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --java_out=lite:$$oldpwd/lite $(conformance_protoc_inputs) $(well_known_type_protoc_inputs) )
touch protoc_middleman
endif
$(protoc_outputs): protoc_middleman
$(other_language_protoc_outputs): protoc_middleman
CLEANFILES = $(protoc_outputs) protoc_middleman javac_middleman conformance-java javac_middleman_lite conformance-java-lite conformance-csharp conformance-php conformance-php-c $(other_language_protoc_outputs)
MAINTAINERCLEANFILES = \
Makefile.in
javac_middleman: ConformanceJava.java protoc_middleman $(other_language_protoc_outputs)
jar=`ls ../java/util/target/*jar-with-dependencies.jar` && javac -classpath ../java/target/classes:$$jar ConformanceJava.java com/google/protobuf/conformance/Conformance.java com/google/protobuf_test_messages/proto3/TestMessagesProto3.java com/google/protobuf_test_messages/proto2/TestMessagesProto2.java
@touch javac_middleman
conformance-java: javac_middleman
@echo "Writing shortcut script conformance-java..."
@echo '#! /bin/sh' > conformance-java
@jar=`ls ../java/util/target/*jar-with-dependencies.jar` && echo java -classpath .:../java/target/classes:$$jar ConformanceJava '$$@' >> conformance-java
@chmod +x conformance-java
javac_middleman_lite: ConformanceJavaLite.java protoc_middleman $(other_language_protoc_outputs)
javac -classpath ../java/lite/target/classes:lite ConformanceJavaLite.java lite/com/google/protobuf/conformance/Conformance.java
@touch javac_middleman_lite
conformance-java-lite: javac_middleman_lite
@echo "Writing shortcut script conformance-java-lite..."
@echo '#! /bin/sh' > conformance-java-lite
@echo java -classpath .:../java/lite/target/classes:lite ConformanceJavaLite '$$@' >> conformance-java-lite
@chmod +x conformance-java-lite
# Currently the conformance code is alongside the rest of the C#
# source, as it's easier to maintain there. We assume we've already
# built that, so we just need a script to run it.
conformance-csharp: $(other_language_protoc_outputs)
@echo "Writing shortcut script conformance-csharp..."
@echo '#! /bin/sh' > conformance-csharp
@echo 'dotnet ../csharp/src/Google.Protobuf.Conformance/bin/Release/netcoreapp3.1/Google.Protobuf.Conformance.dll "$$@"' >> conformance-csharp
@chmod +x conformance-csharp
conformance-php:
@echo "Writing shortcut script conformance-php..."
@echo '#! /bin/sh' > conformance-php
@echo 'php -d auto_prepend_file=autoload.php ./conformance_php.php' >> conformance-php
@chmod +x conformance-php
conformance-php-c:
@echo "Writing shortcut script conformance-php-c..."
@echo '#! /bin/sh' > conformance-php-c
@echo 'php -dextension=../php/ext/google/protobuf/modules/protobuf.so ./conformance_php.php' >> conformance-php-c
@chmod +x conformance-php-c
# Targets for actually running tests.
test_cpp: protoc_middleman conformance-test-runner conformance-cpp
./conformance-test-runner --enforce_recommended --failure_list failure_list_cpp.txt --text_format_failure_list text_format_failure_list_cpp.txt ./conformance-cpp
test_java: protoc_middleman conformance-test-runner conformance-java
./conformance-test-runner --enforce_recommended --failure_list failure_list_java.txt --text_format_failure_list text_format_failure_list_java.txt ./conformance-java
test_java_lite: protoc_middleman conformance-test-runner conformance-java-lite
./conformance-test-runner --enforce_recommended ./conformance-java-lite
test_csharp: protoc_middleman conformance-test-runner conformance-csharp
./conformance-test-runner --enforce_recommended --failure_list failure_list_csharp.txt --text_format_failure_list text_format_failure_list_csharp.txt ./conformance-csharp
test_ruby: protoc_middleman conformance-test-runner $(other_language_protoc_outputs)
RUBYLIB=../ruby/lib:. ./conformance-test-runner --enforce_recommended --failure_list failure_list_ruby.txt --text_format_failure_list text_format_failure_list_ruby.txt ./conformance_ruby.rb
test_jruby: protoc_middleman conformance-test-runner $(other_language_protoc_outputs)
RUBYLIB=../ruby/lib:. ./conformance-test-runner --enforce_recommended --failure_list failure_list_jruby.txt --text_format_failure_list text_format_failure_list_jruby.txt ./conformance_ruby.rb
test_php: protoc_middleman conformance-test-runner conformance-php $(other_language_protoc_outputs)
./conformance-test-runner --enforce_recommended --failure_list failure_list_php.txt --text_format_failure_list text_format_failure_list_php.txt ./conformance-php
test_php_c: protoc_middleman conformance-test-runner conformance-php-c $(other_language_protoc_outputs)
./conformance-test-runner --enforce_recommended --failure_list failure_list_php_c.txt --text_format_failure_list text_format_failure_list_php.txt ./conformance-php-c
# These depend on library paths being properly set up. The easiest way to
# run them is to just use "tox" from the python dir.
test_python: protoc_middleman conformance-test-runner
./conformance-test-runner --enforce_recommended --failure_list failure_list_python.txt --text_format_failure_list text_format_failure_list_python.txt ./conformance_python.py
test_python_cpp: protoc_middleman conformance-test-runner
./conformance-test-runner --enforce_recommended --failure_list failure_list_python_cpp.txt --text_format_failure_list text_format_failure_list_python_cpp.txt ./conformance_python.py
if OBJC_CONFORMANCE_TEST
test_objc: protoc_middleman conformance-test-runner conformance-objc
./conformance-test-runner --enforce_recommended --failure_list failure_list_objc.txt ./conformance-objc
endif

View File

@@ -12,77 +12,44 @@ contains all of the tests themselves. Then separate programs written
in whatever language you want to test communicate with the tester
program over a pipe.
If you're not using Bazel to run these tests, make sure you build the C++
tester code beforehand, e.g. from the base directory:
Before running any of these tests, make sure you run `make` in the base
directory to build `protoc`, since all the tests depend on it.
$ cmake . -Dprotobuf_BUILD_CONFORMANCE=ON && cmake --build .
This will produce a `conformance_test_runner` binary that can be used to run
conformance tests on any executable. Pass it `--help` for more information.
$ make
Running the tests for C++
-------------------------
To run the tests against the C++ implementation, run:
$ bazel test //src:conformance_test
$ cd conformance && make test_cpp
Or alternatively with CMake:
Running the tests for JavaScript (Node.js)
------------------------------------------
$ ctest -R conformance_cpp_test
To run the JavaScript tests against Node.js, make sure you have "node"
on your path and then run:
$ cd conformance && make test_nodejs
Running the tests for Ruby (MRI)
--------------------------------
To run the Ruby tests against MRI, first build the C extension:
$ cd ruby && rake
Then run the tests like so:
$ cd conformance && make test_ruby
Running the tests for other languages
-------------------------------------
All of the languages in the Protobuf source tree are set up to run conformance
tests using similar patterns. You can either use Bazel to run the
`conformance_test` target defined in the language's root `BUILD.bazel` file,
or create an executable for a custom test and pass it to
`conformance_test_runner`.
Note: CMake can be used to build the conformance test runner, but not any of
the conformance test executables outside C++. So if you aren't using Bazel
you'll need to create the executable you pass to `conformance_test_runner` via
some alternate build system.
While we plan to model all our supported languages more completely in Bazel,
today some of them are a bit tricky to run. Below is a list of the commands
(and prerequisites) to run each language's conformance tests.
Java:
$ bazel test //java/core:conformance_test //java/lite:conformance_test
Python:
$ bazel test //python:conformance_test
Python C++:
$ bazel test //python:conformance_test_cpp --define=use_fast_cpp_protos=true
C#:
$ `which dotnet || echo "You must have dotnet installed!"
$ `bazel test //csharp:conformance_test \
--action_env=DOTNET_CLI_TELEMETRY_OPTOUT=1 --test_env=DOTNET_CLI_HOME=~ \
--action_env=DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1
Objective-c (Mac only):
$ `bazel test //objectivec:conformance_test --macos_minimum_os=10.9
Ruby:
$ [[ $(ruby --version) == "ruby"* ]] || echo "Select a C Ruby!"
$ bazel test //ruby:conformance_test --define=ruby_platform=c \
--action_env=PATH --action_env=GEM_PATH --action_env=GEM_HOME
JRuby:
$ [[ $(ruby --version) == "jruby"* ]] || echo "Switch to Java Ruby!"
$ bazel test //ruby:conformance_test_jruby --define=ruby_platform=java \
--action_env=PATH --action_env=GEM_PATH --action_env=GEM_HOME
Most of the languages in the Protobuf source tree are set up to run
conformance tests. However some of them are more tricky to set up
properly. See `tests.sh` in the base of the repository to see how
Kokoro runs the tests.
Testing other Protocol Buffer implementations
---------------------------------------------

View File

@@ -7,7 +7,7 @@ define("GOOGLE_GPBMETADATA_NAMESPACE", "GPBMetadata\\Google\\Protobuf\\");
function protobuf_autoloader_impl($class, $prefix) {
$length = strlen($prefix);
if ((substr($class, 0, $length) === $prefix)) {
$path = 'php/src/' . implode('/', array_map('ucwords', explode('\\', $class))) . '.php';
$path = '../php/src/' . implode('/', array_map('ucwords', explode('\\', $class))) . '.php';
include_once $path;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -31,8 +31,7 @@
#ifndef CONFORMANCE_BINARY_JSON_CONFORMANCE_SUITE_H
#define CONFORMANCE_BINARY_JSON_CONFORMANCE_SUITE_H
#include "google/protobuf/descriptor.h"
#include "json/json.h"
#include "third_party/jsoncpp/json.h"
#include "conformance_test.h"
namespace google {
@@ -44,8 +43,6 @@ class BinaryAndJsonConformanceSuite : public ConformanceTestSuite {
private:
void RunSuiteImpl() override;
void RunBinaryPerformanceTests();
void RunJsonPerformanceTests();
void RunJsonTests();
void RunJsonTestsForFieldNameConvention();
void RunJsonTestsForNonRepeatedTypes();
@@ -59,15 +56,6 @@ class BinaryAndJsonConformanceSuite : public ConformanceTestSuite {
void RunValidJsonTest(const std::string& test_name, ConformanceLevel level,
const std::string& input_json,
const std::string& equivalent_text_format);
void RunValidJsonTest(const std::string& test_name, ConformanceLevel level,
const std::string& input_json,
const std::string& equivalent_text_format,
bool is_proto3);
void RunValidJsonTestWithMessage(const std::string& test_name,
ConformanceLevel level,
const std::string& input_json,
const std::string& equivalent_text_forma,
const Message& prototype);
void RunValidJsonTestWithProtobufInput(
const std::string& test_name, ConformanceLevel level,
const protobuf_test_messages::proto3::TestAllTypesProto3& input,
@@ -90,10 +78,6 @@ class BinaryAndJsonConformanceSuite : public ConformanceTestSuite {
const std::string& input_protobuf,
const std::string& expected_protobuf,
bool is_proto3);
void RunBinaryPerformanceMergeMessageWithField(const std::string& test_name,
const std::string& field_proto,
bool is_proto3);
void RunValidProtobufTestWithMessage(
const std::string& test_name, ConformanceLevel level,
const Message* input, const std::string& equivalent_text_format,
@@ -146,13 +130,6 @@ class BinaryAndJsonConformanceSuite : public ConformanceTestSuite {
void TestValidDataForOneofType(google::protobuf::FieldDescriptor::Type);
void TestMergeOneofMessage();
void TestOverwriteMessageValueMap();
void TestBinaryPerformanceForAlternatingUnknownFields();
void TestBinaryPerformanceMergeMessageWithRepeatedFieldForType(
google::protobuf::FieldDescriptor::Type);
void TestBinaryPerformanceMergeMessageWithUnknownFieldForType(
google::protobuf::FieldDescriptor::Type);
void TestJsonPerformanceMergeMessageWithRepeatedFieldForType(
google::protobuf::FieldDescriptor::Type, std::string field_value);
std::unique_ptr<google::protobuf::util::TypeResolver> type_resolver_;
std::string type_url_;

View File

@@ -29,11 +29,8 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto3";
package conformance;
option java_package = "com.google.protobuf.conformance";
option objc_class_prefix = "Conformance";
// This defines the conformance testing protocol. This protocol exists between
// the conformance test suite itself and the code being tested. For each test,
@@ -72,8 +69,7 @@ enum TestCategory {
// https://developers.google.com/protocol-buffers/docs/proto3#json_options
// for more detail.
JSON_IGNORE_UNKNOWN_PARSING_TEST = 3;
// Test jspb wire format. Google internal only. Opensource testees just skip
// it.
// Test jspb wire format. Google internal only. Opensource testees just skip it.
JSPB_TEST = 4;
// Test text format. For cpp, java and python, testees can already deal with
// this type. Testees of other languages can simply skip it.
@@ -96,6 +92,10 @@ message ConformanceRequest {
// The payload (whether protobuf of JSON) is always for a
// protobuf_test_messages.proto3.TestAllTypes proto (as defined in
// src/google/protobuf/proto3_test_messages.proto).
//
// TODO(haberman): if/when we expand the conformance tests to support proto2,
// we will want to include a field that lets the payload/response be a
// protobuf_test_messages.google.protobuf.TestAllTypes message instead.
oneof payload {
bytes protobuf_payload = 1;
string json_payload = 2;
@@ -113,8 +113,8 @@ message ConformanceRequest {
string message_type = 4;
// Each test is given a specific test category. Some category may need
// specific support in testee programs. Refer to the definition of
// TestCategory for more information.
// specific support in testee programs. Refer to the definition of TestCategory
// for more information.
TestCategory test_category = 5;
// Specify details for how to encode jspb.
@@ -140,11 +140,6 @@ message ConformanceResponse {
// this field.
string serialize_error = 6;
// This should be set if the test program timed out. The string should
// provide more information about what the child process was doing when it
// was killed.
string timeout_error = 9;
// This should be set if some other error occurred. This will always
// indicate that the test failed. The string can provide more information
// about the failure.
@@ -178,3 +173,4 @@ message JspbEncodingConfig {
// Encode the value field of Any as jspb array if true, otherwise binary.
bool use_jspb_array_any_format = 1;
}

View File

@@ -32,175 +32,165 @@
#include <stdarg.h>
#include <unistd.h>
#include <memory>
#include <string>
#include <utility>
#include <google/protobuf/message.h>
#include <google/protobuf/text_format.h>
#include <google/protobuf/util/json_util.h>
#include <google/protobuf/util/type_resolver_util.h>
#include <google/protobuf/stubs/status.h>
#include "conformance.pb.h"
#include <google/protobuf/test_messages_proto2.pb.h>
#include <google/protobuf/test_messages_proto3.pb.h>
#include <google/protobuf/stubs/status.h>
#include "google/protobuf/stubs/logging.h"
#include "google/protobuf/stubs/common.h"
#include "google/protobuf/message.h"
#include "google/protobuf/text_format.h"
#include "google/protobuf/util/json_util.h"
#include "google/protobuf/util/type_resolver_util.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "conformance/conformance.pb.h"
#include "conformance/conformance.pb.h"
#include "google/protobuf/test_messages_proto2.pb.h"
#include "google/protobuf/test_messages_proto3.pb.h"
#include "google/protobuf/test_messages_proto3.pb.h"
#include "google/protobuf/util/type_resolver.h"
#include "google/protobuf/stubs/status_macros.h"
using conformance::ConformanceRequest;
using conformance::ConformanceResponse;
using google::protobuf::Descriptor;
using google::protobuf::DescriptorPool;
using google::protobuf::Message;
using google::protobuf::MessageFactory;
using google::protobuf::TextFormat;
using google::protobuf::util::BinaryToJsonString;
using google::protobuf::util::JsonParseOptions;
using google::protobuf::util::JsonToBinaryString;
using google::protobuf::util::NewTypeResolverForDescriptorPool;
using google::protobuf::util::TypeResolver;
using protobuf_test_messages::proto3::TestAllTypesProto3;
using protobuf_test_messages::proto2::TestAllTypesProto2;
using std::string;
// Must be included last.
#include "google/protobuf/port_def.inc"
static const char kTypeUrlPrefix[] = "type.googleapis.com";
const char* kFailures[] = {
};
static string GetTypeUrl(const Descriptor* message) {
return string(kTypeUrlPrefix) + "/" + message->full_name();
}
int test_count = 0;
bool verbose = false;
TypeResolver* type_resolver;
string* type_url;
namespace google {
namespace protobuf {
namespace {
using ::conformance::ConformanceRequest;
using ::conformance::ConformanceResponse;
using ::google::protobuf::util::BinaryToJsonString;
using ::google::protobuf::util::JsonParseOptions;
using ::google::protobuf::util::JsonToBinaryString;
using ::google::protobuf::util::NewTypeResolverForDescriptorPool;
using ::google::protobuf::util::TypeResolver;
using ::protobuf_test_messages::proto2::TestAllTypesProto2;
using ::protobuf_test_messages::proto3::TestAllTypesProto3;
absl::Status ReadFd(int fd, char* buf, size_t len) {
using util::Status;
bool CheckedRead(int fd, void *buf, size_t len) {
size_t ofs = 0;
while (len > 0) {
ssize_t bytes_read = read(fd, buf, len);
ssize_t bytes_read = read(fd, (char*)buf + ofs, len);
if (bytes_read == 0) {
return absl::DataLossError("unexpected EOF");
}
if (bytes_read == 0) return false;
if (bytes_read < 0) {
return absl::ErrnoToStatus(errno, "error reading from test runner");
GOOGLE_LOG(FATAL) << "Error reading from test runner: " << strerror(errno);
}
len -= bytes_read;
buf += bytes_read;
ofs += bytes_read;
}
return absl::OkStatus();
return true;
}
absl::Status WriteFd(int fd, const void* buf, size_t len) {
if (static_cast<size_t>(write(fd, buf, len)) != len) {
return absl::ErrnoToStatus(errno, "error reading to test runner");
void CheckedWrite(int fd, const void *buf, size_t len) {
if (write(fd, buf, len) != len) {
GOOGLE_LOG(FATAL) << "Error writing to test runner: " << strerror(errno);
}
return absl::OkStatus();
}
class Harness {
public:
Harness() {
google::protobuf::LinkMessageReflection<TestAllTypesProto2>();
google::protobuf::LinkMessageReflection<TestAllTypesProto3>();
resolver_.reset(NewTypeResolverForDescriptorPool(
"type.googleapis.com", DescriptorPool::generated_pool()));
type_url_ = absl::StrCat("type.googleapis.com/",
TestAllTypesProto3::GetDescriptor()->full_name());
void DoTest(const ConformanceRequest& request, ConformanceResponse* response) {
Message *test_message;
google::protobuf::LinkMessageReflection<TestAllTypesProto2>();
google::protobuf::LinkMessageReflection<TestAllTypesProto3>();
const Descriptor *descriptor = DescriptorPool::generated_pool()->FindMessageTypeByName(
request.message_type());
if (!descriptor) {
GOOGLE_LOG(FATAL) << "No such message type: " << request.message_type();
}
absl::StatusOr<ConformanceResponse> RunTest(
const ConformanceRequest& request);
// Returns Ok(true) if we're done processing requests.
absl::StatusOr<bool> ServeConformanceRequest();
private:
bool verbose_ = false;
std::unique_ptr<TypeResolver> resolver_;
std::string type_url_;
};
absl::StatusOr<ConformanceResponse> Harness::RunTest(
const ConformanceRequest& request) {
const Descriptor* descriptor =
DescriptorPool::generated_pool()->FindMessageTypeByName(
request.message_type());
if (descriptor == nullptr) {
return absl::NotFoundError(
absl::StrCat("No such message type: ", request.message_type()));
}
std::unique_ptr<Message> test_message(
MessageFactory::generated_factory()->GetPrototype(descriptor)->New());
ConformanceResponse response;
test_message = MessageFactory::generated_factory()->GetPrototype(descriptor)->New();
switch (request.payload_case()) {
case ConformanceRequest::kProtobufPayload: {
if (!test_message->ParseFromString(request.protobuf_payload())) {
response.set_parse_error("parse error (no more details available)");
return response;
// Getting parse details would involve something like:
// http://stackoverflow.com/questions/22121922/how-can-i-get-more-details-about-errors-generated-during-protobuf-parsing-c
response->set_parse_error("Parse error (no more details available).");
return;
}
break;
}
case ConformanceRequest::kJsonPayload: {
string proto_binary;
JsonParseOptions options;
options.ignore_unknown_fields =
(request.test_category() ==
conformance::JSON_IGNORE_UNKNOWN_PARSING_TEST);
std::string proto_binary;
absl::Status status =
JsonToBinaryString(resolver_.get(), type_url_, request.json_payload(),
conformance::JSON_IGNORE_UNKNOWN_PARSING_TEST);
util::Status status =
JsonToBinaryString(type_resolver, *type_url, request.json_payload(),
&proto_binary, options);
if (!status.ok()) {
response.set_parse_error(
absl::StrCat("parse error: ", status.message()));
return response;
response->set_parse_error(string("Parse error: ") +
std::string(status.message()));
return;
}
if (!test_message->ParseFromString(proto_binary)) {
response.set_runtime_error(
"parsing JSON generated invalid proto output");
return response;
response->set_runtime_error(
"Parsing JSON generates invalid proto output.");
return;
}
break;
}
case ConformanceRequest::kTextPayload: {
if (!TextFormat::ParseFromString(request.text_payload(),
test_message.get())) {
response.set_parse_error("parse error (no more details available)");
return response;
if (!TextFormat::ParseFromString(request.text_payload(), test_message)) {
response->set_parse_error("Parse error");
return;
}
break;
}
case ConformanceRequest::PAYLOAD_NOT_SET:
return absl::InvalidArgumentError("request didn't have payload");
GOOGLE_LOG(FATAL) << "Request didn't have payload.";
break;
default:
return absl::InvalidArgumentError(
absl::StrCat("unknown payload type", request.payload_case()));
GOOGLE_LOG(FATAL) << "unknown payload type: " << request.payload_case();
break;
}
conformance::FailureSet failures;
if (descriptor == failures.GetDescriptor()) {
for (const char* s : kFailures) failures.add_failure(s);
test_message = &failures;
}
switch (request.requested_output_format()) {
case conformance::UNSPECIFIED:
return absl::InvalidArgumentError("unspecified output format");
GOOGLE_LOG(FATAL) << "Unspecified output format";
break;
case conformance::PROTOBUF: {
GOOGLE_CHECK(
test_message->SerializeToString(response.mutable_protobuf_payload()));
GOOGLE_CHECK(test_message->SerializeToString(
response->mutable_protobuf_payload()));
break;
}
case conformance::JSON: {
std::string proto_binary;
string proto_binary;
GOOGLE_CHECK(test_message->SerializeToString(&proto_binary));
absl::Status status =
BinaryToJsonString(resolver_.get(), type_url_, proto_binary,
response.mutable_json_payload());
util::Status status =
BinaryToJsonString(type_resolver, *type_url, proto_binary,
response->mutable_json_payload());
if (!status.ok()) {
response.set_serialize_error(absl::StrCat(
"failed to serialize JSON output: ", status.message()));
response->set_serialize_error(
string("Failed to serialize JSON output: ") +
std::string(status.message()));
return;
}
break;
}
@@ -209,66 +199,70 @@ absl::StatusOr<ConformanceResponse> Harness::RunTest(
TextFormat::Printer printer;
printer.SetHideUnknownFields(!request.print_unknown_fields());
GOOGLE_CHECK(printer.PrintToString(*test_message,
response.mutable_text_payload()));
response->mutable_text_payload()));
break;
}
default:
return absl::InvalidArgumentError(absl::StrCat(
"unknown output format", request.requested_output_format()));
GOOGLE_LOG(FATAL) << "Unknown output format: "
<< request.requested_output_format();
}
return response;
}
absl::StatusOr<bool> Harness::ServeConformanceRequest() {
uint32_t in_len;
if (!ReadFd(STDIN_FILENO, reinterpret_cast<char*>(&in_len), sizeof(in_len))
.ok()) {
// EOF means we're done.
return true;
}
std::string serialized_input;
serialized_input.resize(in_len);
RETURN_IF_ERROR(ReadFd(STDIN_FILENO, &serialized_input[0], in_len));
bool DoTestIo() {
string serialized_input;
string serialized_output;
ConformanceRequest request;
GOOGLE_CHECK(request.ParseFromString(serialized_input));
ConformanceResponse response;
uint32_t bytes;
absl::StatusOr<ConformanceResponse> response = RunTest(request);
RETURN_IF_ERROR(response.status());
std::string serialized_output;
response->SerializeToString(&serialized_output);
uint32_t out_len = static_cast<uint32_t>(serialized_output.size());
RETURN_IF_ERROR(WriteFd(STDOUT_FILENO, &out_len, sizeof(out_len)));
RETURN_IF_ERROR(WriteFd(STDOUT_FILENO, serialized_output.data(), out_len));
if (verbose_) {
GOOGLE_LOG(INFO) << "conformance-cpp: request=" << request.ShortDebugString()
<< ", response=" << response->ShortDebugString();
if (!CheckedRead(STDIN_FILENO, &bytes, sizeof(uint32_t))) {
// EOF.
return false;
}
return false;
serialized_input.resize(bytes);
if (!CheckedRead(STDIN_FILENO, (char*)serialized_input.c_str(), bytes)) {
GOOGLE_LOG(ERROR) << "Unexpected EOF on stdin. " << strerror(errno);
}
if (!request.ParseFromString(serialized_input)) {
GOOGLE_LOG(FATAL) << "Parse of ConformanceRequest proto failed.";
return false;
}
DoTest(request, &response);
response.SerializeToString(&serialized_output);
bytes = serialized_output.size();
CheckedWrite(STDOUT_FILENO, &bytes, sizeof(uint32_t));
CheckedWrite(STDOUT_FILENO, serialized_output.c_str(), bytes);
if (verbose) {
fprintf(stderr, "conformance-cpp: request=%s, response=%s\n",
request.ShortDebugString().c_str(),
response.ShortDebugString().c_str());
}
test_count++;
return true;
}
} // namespace
} // namespace protobuf
} // namespace google
int main() {
google::protobuf::Harness harness;
int total_runs = 0;
while (true) {
auto is_done = harness.ServeConformanceRequest();
if (!is_done.ok()) {
GOOGLE_LOG(FATAL) << is_done.status();
type_resolver = NewTypeResolverForDescriptorPool(
kTypeUrlPrefix, DescriptorPool::generated_pool());
type_url = new string(GetTypeUrl(TestAllTypesProto3::descriptor()));
while (1) {
if (!google::protobuf::DoTestIo()) {
fprintf(stderr, "conformance-cpp: received EOF from test runner "
"after %d tests, exiting\n", test_count);
return 0;
}
if (*is_done) {
break;
}
total_runs++;
}
GOOGLE_LOG(INFO) << "conformance-cpp: received EOF from test runner after "
<< total_runs << " tests";
}

View File

@@ -0,0 +1,189 @@
#!/usr/bin/env node
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
var conformance = require('conformance_pb');
var test_messages_proto3 = require('google/protobuf/test_messages_proto3_pb');
var test_messages_proto2 = require('google/protobuf/test_messages_proto2_pb');
var fs = require('fs');
var testCount = 0;
function doTest(request) {
var testMessage;
var response = new conformance.ConformanceResponse();
try {
if (request.getRequestedOutputFormat() == conformance.WireFormat.JSON) {
response.setSkipped("JSON not supported.");
return response;
}
if (request.getRequestedOutputFormat() ==
conformance.WireFormat.TEXT_FORMAT) {
response.setSkipped('Text format is not supported as output format.');
return response;
}
switch (request.getPayloadCase()) {
case conformance.ConformanceRequest.PayloadCase.PROTOBUF_PAYLOAD: {
if (request.getMessageType() == "protobuf_test_messages.proto3.TestAllTypesProto3") {
try {
testMessage = test_messages_proto3.TestAllTypesProto3.deserializeBinary(
request.getProtobufPayload());
} catch (err) {
response.setParseError(err.toString());
return response;
}
} else if (request.getMessageType() == "protobuf_test_messages.proto2.TestAllTypesProto2"){
try {
testMessage = test_messages_proto2.TestAllTypesProto2.deserializeBinary(
request.getProtobufPayload());
} catch (err) {
response.setParseError(err.toString());
return response;
}
} else {
throw "Protobuf request doesn\'t have specific payload type";
}
} break;
case conformance.ConformanceRequest.PayloadCase.JSON_PAYLOAD:
response.setSkipped("JSON not supported.");
return response;
case conformance.ConformanceRequest.PayloadCase.TEXT_PAYLOAD:
response.setSkipped("Text format not supported.");
return response;
case conformance.ConformanceRequest.PayloadCase.PAYLOAD_NOT_SET:
response.setRuntimeError("Request didn't have payload");
return response;
}
switch (request.getRequestedOutputFormat()) {
case conformance.WireFormat.UNSPECIFIED:
response.setRuntimeError("Unspecified output format");
return response;
case conformance.WireFormat.PROTOBUF:
response.setProtobufPayload(testMessage.serializeBinary());
case conformance.WireFormat.JSON:
response.setSkipped("JSON not supported.");
return response;
default:
throw "Request didn't have requested output format";
}
} catch (err) {
response.setRuntimeError(err.toString());
}
return response;
}
function onEof(totalRead) {
if (totalRead == 0) {
return undefined;
} else {
throw "conformance_nodejs: premature EOF on stdin.";
}
}
// Utility function to read a buffer of N bytes.
function readBuffer(bytes) {
var buf = new Buffer(bytes);
var totalRead = 0;
while (totalRead < bytes) {
var read = 0;
try {
read = fs.readSync(process.stdin.fd, buf, totalRead, bytes - totalRead);
} catch (e) {
if (e.code == 'EOF') {
return onEof(totalRead)
} else if (e.code == 'EAGAIN') {
} else {
throw "conformance_nodejs: Error reading from stdin." + e;
}
}
totalRead += read;
}
return buf;
}
function writeBuffer(buffer) {
var totalWritten = 0;
while (totalWritten < buffer.length) {
totalWritten += fs.writeSync(
process.stdout.fd, buffer, totalWritten, buffer.length - totalWritten);
}
}
// Returns true if the test ran successfully, false on legitimate EOF.
// If EOF is encountered in an unexpected place, raises IOError.
function doTestIo() {
var lengthBuf = readBuffer(4);
if (!lengthBuf) {
return false;
}
var length = lengthBuf.readInt32LE(0);
var serializedRequest = readBuffer(length);
if (!serializedRequest) {
throw "conformance_nodejs: Failed to read request.";
}
serializedRequest = new Uint8Array(serializedRequest);
var request =
conformance.ConformanceRequest.deserializeBinary(serializedRequest);
var response = doTest(request);
var serializedResponse = response.serializeBinary();
lengthBuf = new Buffer(4);
lengthBuf.writeInt32LE(serializedResponse.length, 0);
writeBuffer(lengthBuf);
writeBuffer(new Buffer(serializedResponse));
testCount += 1
return true;
}
while (true) {
if (!doTestIo()) {
console.error('conformance_nodejs: received EOF from test runner ' +
"after " + testCount + " tests, exiting")
break;
}
}

View File

@@ -56,7 +56,8 @@ static NSData *CheckedReadDataOfLength(NSFileHandle *handle, NSUInteger numBytes
return nil; // EOF.
}
if (dataLen != numBytes) {
Die(@"Failed to read the request length (%d), only got: %@", numBytes, data);
Die(@"Failed to read the request length (%d), only got: %@",
numBytes, data);
}
return data;
}
@@ -75,9 +76,8 @@ static ConformanceResponse *DoTest(ConformanceRequest *request) {
Class msgClass = nil;
if ([request.messageType isEqual:@"protobuf_test_messages.proto3.TestAllTypesProto3"]) {
msgClass = [Proto3TestAllTypesProto3 class];
} else if ([request.messageType
isEqual:@"protobuf_test_messages.proto2.TestAllTypesProto2"]) {
msgClass = [Proto2TestAllTypesProto2 class];
} else if ([request.messageType isEqual:@"protobuf_test_messages.proto2.TestAllTypesProto2"]) {
msgClass = [TestAllTypesProto2 class];
} else {
response.runtimeError =
[NSString stringWithFormat:@"Protobuf request had an unknown message_type: %@",
@@ -87,7 +87,8 @@ static ConformanceResponse *DoTest(ConformanceRequest *request) {
NSError *error = nil;
testMessage = [msgClass parseFromData:request.protobufPayload error:&error];
if (!testMessage) {
response.parseError = [NSString stringWithFormat:@"Parse error: %@", error];
response.parseError =
[NSString stringWithFormat:@"Parse error: %@", error];
}
break;
}
@@ -97,8 +98,9 @@ static ConformanceResponse *DoTest(ConformanceRequest *request) {
break;
case ConformanceRequest_Payload_OneOfCase_JspbPayload:
response.skipped = @"ConformanceRequest had a jspb_payload ConformanceRequest.payload;"
" those aren't supposed to happen with opensource.";
response.skipped =
@"ConformanceRequest had a jspb_payload ConformanceRequest.payload;"
" those aren't supposed to happen with opensource.";
break;
case ConformanceRequest_Payload_OneOfCase_TextPayload:
@@ -108,31 +110,31 @@ static ConformanceResponse *DoTest(ConformanceRequest *request) {
if (testMessage) {
switch (request.requestedOutputFormat) {
case ConformanceWireFormat_GPBUnrecognizedEnumeratorValue:
case ConformanceWireFormat_Unspecified:
case WireFormat_GPBUnrecognizedEnumeratorValue:
case WireFormat_Unspecified:
response.runtimeError =
[NSString stringWithFormat:@"Unrecognized/unspecified output format: %@", request];
break;
case ConformanceWireFormat_Protobuf:
case WireFormat_Protobuf:
response.protobufPayload = testMessage.data;
if (!response.protobufPayload) {
response.serializeError =
[NSString stringWithFormat:@"Failed to make data from: %@", testMessage];
[NSString stringWithFormat:@"Failed to make data from: %@", testMessage];
}
break;
case ConformanceWireFormat_Json:
case WireFormat_Json:
response.skipped = @"ObjC doesn't support generating JSON";
break;
case ConformanceWireFormat_Jspb:
case WireFormat_Jspb:
response.skipped =
@"ConformanceRequest had a requested_output_format of JSPB WireFormat; that"
" isn't supposed to happen with opensource.";
" isn't supposed to happen with opensource.";
break;
case ConformanceWireFormat_TextFormat:
case WireFormat_TextFormat:
// ObjC only has partial objc generation, so don't attempt any tests that need
// support.
response.skipped = @"ObjC doesn't support generating TextFormat";
@@ -171,7 +173,8 @@ static BOOL DoTestIo(NSFileHandle *input, NSFileHandle *output) {
}
NSError *error = nil;
ConformanceRequest *request = [ConformanceRequest parseFromData:data error:&error];
ConformanceRequest *request = [ConformanceRequest parseFromData:data
error:&error];
if (!request) {
Die(@"Failed to parse the message data: %@", error);
}

View File

@@ -14,7 +14,7 @@ require_once("Protobuf_test_messages/Proto3/TestAllTypesProto3/NestedMessage.php
require_once("Protobuf_test_messages/Proto3/TestAllTypesProto3/NestedEnum.php");
require_once("GPBMetadata/Conformance.php");
require_once("GPBMetadata/TestMessagesProto3.php");
require_once("GPBMetadata/Google/Protobuf/TestMessagesProto3.php");
use \Conformance\TestCategory;
use \Conformance\WireFormat;
@@ -113,7 +113,7 @@ function doTestIO()
while(true){
if (!doTestIO()) {
fprintf(STDERR,
"conformance_php: received EOF from test runner " .
"conformance_php: received EOF from test runner " +
"after %d tests, exiting\n", $test_count);
exit;
}

View File

@@ -42,7 +42,7 @@ from google.protobuf import message
from google.protobuf import test_messages_proto3_pb2
from google.protobuf import test_messages_proto2_pb2
from google.protobuf import text_format
from conformance import conformance_pb2
import conformance_pb2
sys.stdout = os.fdopen(sys.stdout.fileno(), 'wb', 0)
sys.stdin = os.fdopen(sys.stdin.fileno(), 'rb', 0)

View File

@@ -36,15 +36,13 @@
#include <set>
#include <string>
#include "google/protobuf/message.h"
#include "google/protobuf/text_format.h"
#include "google/protobuf/util/field_comparator.h"
#include "google/protobuf/util/json_util.h"
#include "google/protobuf/util/message_differencer.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
#include "conformance/conformance.pb.h"
#include "conformance/conformance.pb.h"
#include <google/protobuf/stubs/stringprintf.h>
#include <google/protobuf/message.h>
#include <google/protobuf/text_format.h>
#include <google/protobuf/util/field_comparator.h>
#include <google/protobuf/util/json_util.h>
#include <google/protobuf/util/message_differencer.h>
#include "conformance.pb.h"
using conformance::ConformanceRequest;
using conformance::ConformanceResponse;
@@ -131,7 +129,7 @@ string ConformanceTestSuite::ConformanceRequestSetting::
prototype_message_.GetDescriptor()->file()->syntax() ==
FileDescriptor::SYNTAX_PROTO3 ? "Proto3" : "Proto2";
return absl::StrCat(ConformanceLevelToString(level_), ".", rname, ".",
return StrCat(ConformanceLevelToString(level_), ".", rname, ".",
InputFormatString(input_format_), ".", test_name_, ".",
OutputFormatString(output_format_));
}
@@ -177,66 +175,12 @@ string ConformanceTestSuite::ConformanceRequestSetting::
return "";
}
void ConformanceTestSuite::TruncateDebugPayload(string* payload) {
if (payload != nullptr && payload->size() > 200) {
payload->resize(200);
payload->append("...(truncated)");
}
}
const ConformanceRequest ConformanceTestSuite::TruncateRequest(
const ConformanceRequest& request) {
ConformanceRequest debug_request(request);
switch (debug_request.payload_case()) {
case ConformanceRequest::kProtobufPayload:
TruncateDebugPayload(debug_request.mutable_protobuf_payload());
break;
case ConformanceRequest::kJsonPayload:
TruncateDebugPayload(debug_request.mutable_json_payload());
break;
case ConformanceRequest::kTextPayload:
TruncateDebugPayload(debug_request.mutable_text_payload());
break;
case ConformanceRequest::kJspbPayload:
TruncateDebugPayload(debug_request.mutable_jspb_payload());
break;
default:
// Do nothing.
break;
}
return debug_request;
}
const ConformanceResponse ConformanceTestSuite::TruncateResponse(
const ConformanceResponse& response) {
ConformanceResponse debug_response(response);
switch (debug_response.result_case()) {
case ConformanceResponse::kProtobufPayload:
TruncateDebugPayload(debug_response.mutable_protobuf_payload());
break;
case ConformanceResponse::kJsonPayload:
TruncateDebugPayload(debug_response.mutable_json_payload());
break;
case ConformanceResponse::kTextPayload:
TruncateDebugPayload(debug_response.mutable_text_payload());
break;
case ConformanceResponse::kJspbPayload:
TruncateDebugPayload(debug_response.mutable_jspb_payload());
break;
default:
// Do nothing.
break;
}
return debug_response;
}
void ConformanceTestSuite::ReportSuccess(const string& test_name) {
if (expected_to_fail_.erase(test_name) != 0) {
absl::StrAppendFormat(
&output_,
"ERROR: test %s is in the failure list, but test succeeded. "
"Remove it from the failure list.\n",
test_name);
StringAppendF(&output_,
"ERROR: test %s is in the failure list, but test succeeded. "
"Remove it from the failure list.\n",
test_name.c_str());
unexpected_succeeding_tests_.insert(test_name);
}
successes_++;
@@ -246,30 +190,33 @@ void ConformanceTestSuite::ReportFailure(const string& test_name,
ConformanceLevel level,
const ConformanceRequest& request,
const ConformanceResponse& response,
absl::string_view message) {
const char* fmt, ...) {
if (expected_to_fail_.erase(test_name) == 1) {
expected_failures_++;
if (!verbose_)
return;
} else if (level == RECOMMENDED && !enforce_recommended_) {
absl::StrAppendFormat(&output_, "WARNING, test=%s: ", test_name);
StringAppendF(&output_, "WARNING, test=%s: ", test_name.c_str());
} else {
absl::StrAppendFormat(&output_, "ERROR, test=%s: ", test_name);
StringAppendF(&output_, "ERROR, test=%s: ", test_name.c_str());
unexpected_failing_tests_.insert(test_name);
}
absl::StrAppendFormat(&output_, "%s, request=%s, response=%s\n", message,
TruncateRequest(request).ShortDebugString(),
TruncateResponse(response).ShortDebugString());
va_list args;
va_start(args, fmt);
StringAppendV(&output_, fmt, args);
va_end(args);
StringAppendF(&output_, " request=%s, response=%s\n",
request.ShortDebugString().c_str(),
response.ShortDebugString().c_str());
}
void ConformanceTestSuite::ReportSkip(const string& test_name,
const ConformanceRequest& request,
const ConformanceResponse& response) {
if (verbose_) {
absl::StrAppendFormat(
&output_, "SKIPPED, test=%s request=%s, response=%s\n", test_name,
request.ShortDebugString(), response.ShortDebugString());
StringAppendF(&output_, "SKIPPED, test=%s request=%s, response=%s\n",
test_name.c_str(), request.ShortDebugString().c_str(),
response.ShortDebugString().c_str());
}
skipped_.insert(test_name);
}
@@ -316,7 +263,6 @@ void ConformanceTestSuite::VerifyResponse(
return;
case ConformanceResponse::kParseError:
case ConformanceResponse::kTimeoutError:
case ConformanceResponse::kRuntimeError:
case ConformanceResponse::kSerializeError:
ReportFailure(test_name, level, request, response,
@@ -344,7 +290,7 @@ void ConformanceTestSuite::VerifyResponse(
GOOGLE_DCHECK_EQ(response.result_case(), ConformanceResponse::kProtobufPayload);
const string& protobuf_payload = response.protobuf_payload();
check = equivalent_wire_format == protobuf_payload;
differences = absl::StrCat("Expect: ", ToOctString(equivalent_wire_format),
differences = StrCat("Expect: ", ToOctString(equivalent_wire_format),
", but got: ", ToOctString(protobuf_payload));
} else {
check = differencer.Compare(*reference_message, *test_message);
@@ -355,10 +301,9 @@ void ConformanceTestSuite::VerifyResponse(
ReportSuccess(test_name);
}
} else {
ReportFailure(
test_name, level, request, response,
absl::StrCat("Output was not equivalent to reference message: ",
differences));
ReportFailure(test_name, level, request, response,
"Output was not equivalent to reference message: %s.",
differences.c_str());
}
}
@@ -381,10 +326,11 @@ void ConformanceTestSuite::RunTest(const string& test_name,
}
if (verbose_) {
absl::StrAppendFormat(
&output_, "conformance test: name=%s, request=%s, response=%s\n",
test_name, TruncateRequest(request).ShortDebugString(),
TruncateResponse(*response).ShortDebugString());
StringAppendF(&output_,
"conformance test: name=%s, request=%s, response=%s\n",
test_name.c_str(),
request.ShortDebugString().c_str(),
response->ShortDebugString().c_str());
}
}
@@ -395,12 +341,13 @@ bool ConformanceTestSuite::CheckSetEmpty(
if (set_to_check.empty()) {
return true;
} else {
absl::StrAppendFormat(&output_, "\n");
absl::StrAppendFormat(&output_, "%s\n\n", msg);
for (absl::string_view v : set_to_check) {
absl::StrAppendFormat(&output_, " %s\n", v);
StringAppendF(&output_, "\n");
StringAppendF(&output_, "%s\n\n", msg.c_str());
for (std::set<string>::const_iterator iter = set_to_check.begin();
iter != set_to_check.end(); ++iter) {
StringAppendF(&output_, " %s\n", iter->c_str());
}
absl::StrAppendFormat(&output_, "\n");
StringAppendF(&output_, "\n");
if (!write_to_file.empty()) {
std::string full_filename;
@@ -415,11 +362,13 @@ bool ConformanceTestSuite::CheckSetEmpty(
}
std::ofstream os(*filename);
if (os) {
for (absl::string_view v : set_to_check) {
os << v << "\n";
for (std::set<string>::const_iterator iter = set_to_check.begin();
iter != set_to_check.end(); ++iter) {
os << *iter << "\n";
}
} else {
absl::StrAppendFormat(&output_, "Failed to open file: %s\n", *filename);
StringAppendF(&output_, "Failed to open file: %s\n",
filename->c_str());
}
}
@@ -503,12 +452,12 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner,
"features is not implemented)");
}
absl::StrAppendFormat(&output_,
"CONFORMANCE SUITE %s: %d successes, %zu skipped, "
"%d expected failures, %zu unexpected failures.\n",
ok ? "PASSED" : "FAILED", successes_, skipped_.size(),
expected_failures_, unexpected_failing_tests_.size());
absl::StrAppendFormat(&output_, "\n");
StringAppendF(&output_,
"CONFORMANCE SUITE %s: %d successes, %zu skipped, "
"%d expected failures, %zu unexpected failures.\n",
ok ? "PASSED" : "FAILED", successes_, skipped_.size(),
expected_failures_, unexpected_failing_tests_.size());
StringAppendF(&output_, "\n");
output->assign(output_);

View File

@@ -42,10 +42,10 @@
#include <string>
#include <vector>
#include "google/protobuf/descriptor.h"
#include "google/protobuf/wire_format_lite.h"
#include "google/protobuf/util/type_resolver.h"
#include "conformance/conformance.pb.h"
#include <google/protobuf/descriptor.h>
#include <google/protobuf/wire_format_lite.h>
#include <google/protobuf/util/type_resolver.h>
#include "conformance.pb.h"
namespace conformance {
class ConformanceRequest;
@@ -88,12 +88,10 @@ class ForkPipeRunner : public ConformanceTestRunner {
const std::vector<ConformanceTestSuite*>& suites);
ForkPipeRunner(const std::string& executable,
const std::vector<std::string>& executable_args,
bool performance)
const std::vector<std::string>& executable_args)
: child_pid_(-1),
executable_(executable),
executable_args_(executable_args),
performance_(performance) {}
executable_args_(executable_args) {}
explicit ForkPipeRunner(const std::string& executable)
: child_pid_(-1), executable_(executable) {}
@@ -116,7 +114,6 @@ class ForkPipeRunner : public ConformanceTestRunner {
pid_t child_pid_;
std::string executable_;
const std::vector<std::string> executable_args_;
bool performance_;
std::string current_test_name_;
};
@@ -151,12 +148,10 @@ class ConformanceTestSuite {
public:
ConformanceTestSuite()
: verbose_(false),
performance_(false),
enforce_recommended_(false),
failure_list_flag_name_("--failure_list") {}
virtual ~ConformanceTestSuite() {}
void SetPerformance(bool performance) { performance_ = performance; }
void SetVerbose(bool verbose) { verbose_ = verbose; }
// Whether to require the testee to pass RECOMMENDED tests. By default failing
@@ -277,17 +272,11 @@ class ConformanceTestSuite {
const conformance::ConformanceResponse& response,
bool need_report_success, bool require_same_wire_format);
void TruncateDebugPayload(std::string* payload);
const conformance::ConformanceRequest TruncateRequest(
const conformance::ConformanceRequest& request);
const conformance::ConformanceResponse TruncateResponse(
const conformance::ConformanceResponse& response);
void ReportSuccess(const std::string& test_name);
void ReportFailure(const std::string& test_name, ConformanceLevel level,
const conformance::ConformanceRequest& request,
const conformance::ConformanceResponse& response,
absl::string_view message);
const char* fmt, ...);
void ReportSkip(const std::string& test_name,
const conformance::ConformanceRequest& request,
const conformance::ConformanceResponse& response);
@@ -310,7 +299,6 @@ class ConformanceTestSuite {
int successes_;
int expected_failures_;
bool verbose_;
bool performance_;
bool enforce_recommended_;
std::string output_;
std::string output_dir_;

View File

@@ -54,19 +54,16 @@
// 4. testee sends M bytes representing a ConformanceResponse proto
#include <errno.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <algorithm>
#include <cstdlib>
#include <fstream>
#include <future>
#include <vector>
#include "absl/strings/str_format.h"
#include "conformance/conformance.pb.h"
#include <google/protobuf/stubs/stringprintf.h>
#include "conformance.pb.h"
#include "conformance_test.h"
using conformance::ConformanceResponse;
@@ -76,10 +73,10 @@ using std::vector;
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define GOOGLE_CHECK_SYSCALL(call) \
if (call < 0) { \
#define GOOGLE_CHECK_SYSCALL(call) \
if (call < 0) { \
perror(#call " " __FILE__ ":" TOSTRING(__LINE__)); \
exit(1); \
exit(1); \
}
namespace google {
@@ -96,7 +93,8 @@ void ParseFailureList(const char *filename,
for (string line; getline(infile, line);) {
// Remove whitespace.
line.erase(std::remove_if(line.begin(), line.end(), ::isspace), line.end());
line.erase(std::remove_if(line.begin(), line.end(), ::isspace),
line.end());
// Remove comments.
line = line.substr(0, line.find("#"));
@@ -108,7 +106,8 @@ void ParseFailureList(const char *filename,
}
void UsageError() {
fprintf(stderr, "Usage: conformance-test-runner [options] <test-program>\n");
fprintf(stderr,
"Usage: conformance-test-runner [options] <test-program>\n");
fprintf(stderr, "\n");
fprintf(stderr, "Options:\n");
fprintf(stderr,
@@ -123,7 +122,8 @@ void UsageError() {
" --text_format_failure_list <filename> Use to specify list \n");
fprintf(stderr,
" of tests that are expected to \n");
fprintf(stderr, " fail in the \n");
fprintf(stderr,
" fail in the \n");
fprintf(stderr,
" text_format_conformance_suite. \n");
fprintf(stderr,
@@ -139,19 +139,22 @@ void UsageError() {
" this flag if you want to be\n");
fprintf(stderr,
" strictly conforming to protobuf\n");
fprintf(stderr, " spec.\n");
fprintf(stderr,
" spec.\n");
fprintf(stderr,
" --output_dir <dirname> Directory to write\n"
" output files.\n");
exit(1);
}
void ForkPipeRunner::RunTest(const std::string &test_name,
const std::string &request,
std::string *response) {
void ForkPipeRunner::RunTest(
const std::string& test_name,
const std::string& request,
std::string* response) {
if (child_pid_ < 0) {
SpawnTestProgram();
}
current_test_name_ = test_name;
uint32_t len = request.size();
@@ -166,55 +169,44 @@ void ForkPipeRunner::RunTest(const std::string &test_name,
waitpid(child_pid_, &status, WEXITED);
string error_msg;
conformance::ConformanceResponse response_obj;
if (WIFEXITED(status)) {
if (WEXITSTATUS(status) == 0) {
absl::StrAppendFormat(&error_msg,
"child timed out, killed by signal %d",
WTERMSIG(status));
response_obj.set_timeout_error(error_msg);
} else {
absl::StrAppendFormat(&error_msg, "child exited, status=%d",
WEXITSTATUS(status));
response_obj.set_runtime_error(error_msg);
}
StringAppendF(&error_msg,
"child exited, status=%d", WEXITSTATUS(status));
} else if (WIFSIGNALED(status)) {
absl::StrAppendFormat(&error_msg, "child killed by signal %d",
WTERMSIG(status));
StringAppendF(&error_msg,
"child killed by signal %d", WTERMSIG(status));
}
GOOGLE_LOG(INFO) << error_msg;
child_pid_ = -1;
conformance::ConformanceResponse response_obj;
response_obj.set_runtime_error(error_msg);
response_obj.SerializeToString(response);
return;
}
response->resize(len);
CheckedRead(read_fd_, (void *)response->c_str(), len);
CheckedRead(read_fd_, (void*)response->c_str(), len);
}
int ForkPipeRunner::Run(int argc, char *argv[],
const std::vector<ConformanceTestSuite *> &suites) {
int ForkPipeRunner::Run(
int argc, char *argv[], const std::vector<ConformanceTestSuite*>& suites) {
if (suites.empty()) {
fprintf(stderr, "No test suites found.\n");
return EXIT_FAILURE;
}
bool all_ok = true;
for (ConformanceTestSuite *suite : suites) {
for (ConformanceTestSuite* suite : suites) {
string program;
std::vector<string> program_args;
string failure_list_filename;
conformance::FailureSet failure_list;
bool performance = false;
for (int arg = 1; arg < argc; ++arg) {
if (strcmp(argv[arg], suite->GetFailureListFlagName().c_str()) == 0) {
if (++arg == argc) UsageError();
failure_list_filename = argv[arg];
ParseFailureList(argv[arg], &failure_list);
} else if (strcmp(argv[arg], "--performance") == 0) {
performance = true;
suite->SetPerformance(true);
} else if (strcmp(argv[arg], "--verbose") == 0) {
suite->SetVerbose(true);
} else if (strcmp(argv[arg], "--enforce_recommended") == 0) {
@@ -224,7 +216,7 @@ int ForkPipeRunner::Run(int argc, char *argv[],
suite->SetOutputDir(argv[arg]);
} else if (argv[arg][0] == '-') {
bool recognized_flag = false;
for (ConformanceTestSuite *suite : suites) {
for (ConformanceTestSuite* suite : suites) {
if (strcmp(argv[arg], suite->GetFailureListFlagName().c_str()) == 0) {
if (++arg == argc) UsageError();
recognized_flag = true;
@@ -235,7 +227,7 @@ int ForkPipeRunner::Run(int argc, char *argv[],
UsageError();
}
} else {
program += argv[arg++];
program += argv[arg];
while (arg < argc) {
program_args.push_back(argv[arg]);
arg++;
@@ -243,11 +235,11 @@ int ForkPipeRunner::Run(int argc, char *argv[],
}
}
ForkPipeRunner runner(program, program_args, performance);
ForkPipeRunner runner(program, program_args);
std::string output;
all_ok = all_ok && suite->RunSuite(&runner, &output, failure_list_filename,
&failure_list);
all_ok = all_ok &&
suite->RunSuite(&runner, &output, failure_list_filename, &failure_list);
fwrite(output.c_str(), 1, output.size(), stderr);
}
@@ -311,10 +303,8 @@ void ForkPipeRunner::SpawnTestProgram() {
std::vector<const char *> argv;
argv.push_back(executable.get());
GOOGLE_LOG(INFO) << argv[0];
for (size_t i = 0; i < executable_args_.size(); ++i) {
argv.push_back(executable_args_[i].c_str());
GOOGLE_LOG(INFO) << executable_args_[i];
}
argv.push_back(nullptr);
// Never returns.
@@ -332,36 +322,8 @@ void ForkPipeRunner::CheckedWrite(int fd, const void *buf, size_t len) {
bool ForkPipeRunner::TryRead(int fd, void *buf, size_t len) {
size_t ofs = 0;
while (len > 0) {
std::future<ssize_t> future = std::async(
std::launch::async,
[](int fd, void *buf, size_t ofs, size_t len) {
return read(fd, (char *)buf + ofs, len);
},
fd, buf, ofs, len);
std::future_status status;
if (performance_) {
status = future.wait_for(std::chrono::seconds(5));
if (status == std::future_status::timeout) {
GOOGLE_LOG(ERROR) << current_test_name_ << ": timeout from test program";
kill(child_pid_, SIGQUIT);
// TODO(sandyzhang): Only log in flag-guarded mode, since reading output
// from SIGQUIT is slow and verbose.
std::vector<char> err;
err.resize(5000);
ssize_t err_bytes_read;
size_t err_ofs = 0;
do {
err_bytes_read =
read(fd, (void *)&err[err_ofs], err.size() - err_ofs);
err_ofs += err_bytes_read;
} while (err_bytes_read > 0 && err_ofs < err.size());
GOOGLE_LOG(ERROR) << "child_pid_=" << child_pid_ << " SIGQUIT: \n" << &err[0];
return false;
}
} else {
future.wait();
}
ssize_t bytes_read = future.get();
ssize_t bytes_read = read(fd, (char*)buf + ofs, len);
if (bytes_read == 0) {
GOOGLE_LOG(ERROR) << current_test_name_ << ": unexpected EOF from test program";
return false;

View File

@@ -1,7 +1,4 @@
#!/bin/bash
# This is an internal file that should only be called from Bazel rules. For
# custom conformance tests outside of Bazel use CMAKE with
# -Dprotobuf_BUILD_CONFORMANCE=ON to build the test runner.
set -x
echo $@
@@ -47,13 +44,13 @@ conformance_test_runner=$(rlocation com_google_protobuf/conformance/conformance_
conformance_testee=$(rlocation $TESTEE)
args=(--enforce_recommended)
failure_list=$(rlocation $FAILURE_LIST) || unset
if [ -n "$failure_list" ] ; then
failure_list=$(rlocation $FAILURE_LIST)
if [ "$failure_list" != "1" ] ; then
args+=(--failure_list $failure_list)
fi
text_format_failure_list=$(rlocation $TEXT_FORMAT_FAILURE_LIST) || unset
if [ -n "$text_format_failure_list" ]; then
text_format_failure_list=$(rlocation $TEXT_FORMAT_FAILURE_LIST)
if [ "$text_format_failure_list" != "1" ]; then
args+=(--text_format_failure_list $text_format_failure_list)
fi

View File

@@ -1,24 +1,6 @@
"""Starlark definitions for Protobuf conformance tests.
# PLEASE DO NOT DEPEND ON THE CONTENTS OF THIS FILE, IT IS UNSTABLE.
PLEASE DO NOT DEPEND ON THE CONTENTS OF THIS FILE, IT IS UNSTABLE.
"""
def conformance_test(
name,
testee,
failure_list = None,
text_format_failure_list = None,
**kwargs):
"""Conformance test runner.
Args:
name: the name for the test.
testee: a conformance test client binary.
failure_list: a text file with known failures, one per line.
text_format_failure_list: a text file with known failures (one per line)
for the text format conformance suite.
**kwargs: common arguments to pass to sh_test.
"""
def conformance_test(name, testee, failure_list = None, text_format_failure_list = None):
args = ["--testee %s" % _strip_bazel(testee)]
failure_lists = []
if failure_list:
@@ -30,7 +12,7 @@ def conformance_test(
native.sh_test(
name = name,
srcs = ["//conformance:bazel_conformance_test_runner.sh"],
srcs = ["//conformance:conformance_test_runner.sh"],
data = [testee] + failure_lists + [
"//conformance:conformance_test_runner",
],
@@ -38,8 +20,6 @@ def conformance_test(
deps = [
"@bazel_tools//tools/bash/runfiles",
],
tags = ["conformance"],
**kwargs
)
def _strip_bazel(testee):

View File

@@ -12,6 +12,8 @@ Recommended.FieldMaskPathsDontRoundTrip.JsonOutput
Recommended.FieldMaskTooManyUnderscore.JsonOutput
Recommended.Proto3.JsonInput.BoolFieldDoubleQuotedFalse
Recommended.Proto3.JsonInput.BoolFieldDoubleQuotedTrue
Recommended.Proto3.JsonInput.BytesFieldBase64Url.JsonOutput
Recommended.Proto3.JsonInput.BytesFieldBase64Url.ProtobufOutput
Recommended.Proto3.JsonInput.FieldMaskInvalidCharacter
Recommended.Proto3.JsonInput.FieldNameDuplicate
Recommended.Proto3.JsonInput.FieldNameDuplicateDifferentCasing1

View File

@@ -0,0 +1,162 @@
Recommended.Proto2.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.PackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.PackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.PackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT32.PackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT32.PackedInput.PackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT32.PackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.PackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT64.PackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT64.PackedInput.PackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT64.PackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.PackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.PackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.PackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.PackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.PackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.PackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.PackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.PackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.PackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataScalarBinary.ENUM[4].ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataScalarBinary.ENUM[5].ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataScalarBinary.FIXED64[2].ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataScalarBinary.INT32[7].ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataScalarBinary.INT64[2].ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataScalarBinary.SFIXED64[2].ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataScalarBinary.SINT64[2].ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataScalarBinary.UINT32[8].ProtobufOutput
Recommended.Proto2.ProtobufInput.ValidDataScalarBinary.UINT64[2].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.PackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.PackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.PackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.PackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.PackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.PackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.PackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.PackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.PackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.PackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.PackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.PackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.PackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.PackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.DefaultOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.PackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.UnpackedOutput.ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.ENUM[4].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.ENUM[5].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.FIXED64[2].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.INT32[7].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.INT64[2].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.SFIXED64[2].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.SINT64[2].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.UINT32[8].ProtobufOutput
Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.UINT64[2].ProtobufOutput
Required.Proto2.ProtobufInput.RepeatedScalarSelectsLast.ENUM.ProtobufOutput
Required.Proto2.ProtobufInput.RepeatedScalarSelectsLast.FIXED64.ProtobufOutput
Required.Proto2.ProtobufInput.RepeatedScalarSelectsLast.UINT64.ProtobufOutput
Required.Proto2.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.ProtobufOutput
Required.Proto2.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.ProtobufOutput
Required.Proto2.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.ProtobufOutput
Required.Proto2.ProtobufInput.ValidDataRepeated.INT32.PackedInput.ProtobufOutput
Required.Proto2.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.ProtobufOutput
Required.Proto2.ProtobufInput.ValidDataRepeated.INT64.PackedInput.ProtobufOutput
Required.Proto2.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.ProtobufOutput
Required.Proto2.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.ProtobufOutput
Required.Proto2.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.ProtobufOutput
Required.Proto2.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.ProtobufOutput
Required.Proto2.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.ProtobufOutput
Required.Proto2.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.ProtobufOutput
Required.Proto2.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.ProtobufOutput
Required.Proto2.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.ProtobufOutput
Required.Proto2.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.ProtobufOutput
Required.Proto2.ProtobufInput.ValidDataScalar.ENUM[4].ProtobufOutput
Required.Proto2.ProtobufInput.ValidDataScalar.ENUM[5].ProtobufOutput
Required.Proto2.ProtobufInput.ValidDataScalar.FIXED64[2].ProtobufOutput
Required.Proto2.ProtobufInput.ValidDataScalar.INT32[7].ProtobufOutput
Required.Proto2.ProtobufInput.ValidDataScalar.INT64[2].ProtobufOutput
Required.Proto2.ProtobufInput.ValidDataScalar.SFIXED64[2].ProtobufOutput
Required.Proto2.ProtobufInput.ValidDataScalar.SINT64[2].ProtobufOutput
Required.Proto2.ProtobufInput.ValidDataScalar.UINT32[8].ProtobufOutput
Required.Proto2.ProtobufInput.ValidDataScalar.UINT64[2].ProtobufOutput
Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.ENUM.ProtobufOutput
Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.FIXED64.ProtobufOutput
Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.UINT64.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.ENUM[4].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.ENUM[5].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.FIXED64[2].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.INT32[7].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.INT64[2].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.SFIXED64[2].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.SINT64[2].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.UINT32[8].ProtobufOutput
Required.Proto3.ProtobufInput.ValidDataScalar.UINT64[2].ProtobufOutput

View File

@@ -8,8 +8,6 @@ Recommended.Proto3.JsonInput.FieldMaskInvalidCharacter
Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.MESSAGE.Merge.ProtobufOutput
Required.Proto2.JsonInput.StoresDefaultPrimitive.Validator
Required.Proto3.JsonInput.DoubleFieldTooSmall
Required.Proto3.JsonInput.DurationNegativeNanos.JsonOutput
Required.Proto3.JsonInput.DurationNegativeNanos.ProtobufOutput
Required.Proto3.JsonInput.FloatFieldTooLarge
Required.Proto3.JsonInput.FloatFieldTooSmall
Required.Proto3.JsonInput.Int32FieldNotInteger

View File

@@ -30,11 +30,11 @@
#include "text_format_conformance_suite.h"
#include "google/protobuf/any.pb.h"
#include "google/protobuf/text_format.h"
#include <google/protobuf/any.pb.h>
#include <google/protobuf/text_format.h>
#include "conformance_test.h"
#include "google/protobuf/test_messages_proto2.pb.h"
#include "google/protobuf/test_messages_proto3.pb.h"
#include <google/protobuf/test_messages_proto2.pb.h>
#include <google/protobuf/test_messages_proto3.pb.h>
namespace proto2_messages = protobuf_test_messages::proto2;
@@ -51,10 +51,6 @@ using std::string;
namespace google {
namespace protobuf {
// The number of repetitions to use for performance tests.
// Corresponds approx to 500KB wireformat bytes.
static const size_t kPerformanceRepeatCount = 50000;
TextFormatConformanceTestSuite::TextFormatConformanceTestSuite() {
SetFailureListFlagName("--text_format_failure_list");
}
@@ -89,9 +85,10 @@ bool TextFormatConformanceTestSuite::ParseResponse(
case ConformanceResponse::kProtobufPayload: {
if (requested_output != conformance::PROTOBUF) {
ReportFailure(test_name, level, request, response,
absl::StrCat("Test was asked for ",
StrCat("Test was asked for ",
WireFormatToString(requested_output),
" output but provided PROTOBUF instead."));
" output but provided PROTOBUF instead.")
.c_str());
return false;
}
@@ -106,11 +103,11 @@ bool TextFormatConformanceTestSuite::ParseResponse(
case ConformanceResponse::kTextPayload: {
if (requested_output != conformance::TEXT_FORMAT) {
ReportFailure(
test_name, level, request, response,
absl::StrCat("Test was asked for ",
WireFormatToString(requested_output),
" output but provided TEXT_FORMAT instead."));
ReportFailure(test_name, level, request, response,
StrCat("Test was asked for ",
WireFormatToString(requested_output),
" output but provided TEXT_FORMAT instead.")
.c_str());
return false;
}
@@ -144,7 +141,7 @@ void TextFormatConformanceTestSuite::ExpectParseFailure(const string& test_name,
const ConformanceRequest& request = setting.GetRequest();
ConformanceResponse response;
string effective_test_name =
absl::StrCat(setting.ConformanceLevelToString(level),
StrCat(setting.ConformanceLevelToString(level),
".Proto3.TextFormatInput.", test_name);
RunTest(effective_test_name, request, &response);
@@ -170,22 +167,6 @@ void TextFormatConformanceTestSuite::RunValidTextFormatTestProto2(
RunValidTextFormatTestWithMessage(test_name, level, input_text, prototype);
}
void TextFormatConformanceTestSuite::RunValidTextFormatTestWithExpected(
const string& test_name, ConformanceLevel level, const string& input_text,
const string& expected_text) {
TestAllTypesProto3 prototype;
RunValidTextFormatTestWithMessage(test_name, level, input_text, expected_text,
prototype);
}
void TextFormatConformanceTestSuite::RunValidTextFormatTestProto2WithExpected(
const string& test_name, ConformanceLevel level, const string& input_text,
const string& expected_text) {
TestAllTypesProto2 prototype;
RunValidTextFormatTestWithMessage(test_name, level, input_text, expected_text,
prototype);
}
void TextFormatConformanceTestSuite::RunValidTextFormatTestWithMessage(
const string& test_name, ConformanceLevel level, const string& input_text,
const Message& prototype) {
@@ -199,19 +180,6 @@ void TextFormatConformanceTestSuite::RunValidTextFormatTestWithMessage(
RunValidInputTest(setting2, input_text);
}
void TextFormatConformanceTestSuite::RunValidTextFormatTestWithMessage(
const string& test_name, ConformanceLevel level, const string& input_text,
const string& expected_text, const Message& prototype) {
ConformanceRequestSetting setting1(
level, conformance::TEXT_FORMAT, conformance::PROTOBUF,
conformance::TEXT_FORMAT_TEST, prototype, test_name, input_text);
RunValidInputTest(setting1, expected_text);
ConformanceRequestSetting setting2(
level, conformance::TEXT_FORMAT, conformance::TEXT_FORMAT,
conformance::TEXT_FORMAT_TEST, prototype, test_name, input_text);
RunValidInputTest(setting2, expected_text);
}
void TextFormatConformanceTestSuite::RunValidUnknownTextFormatTest(
const string& test_name, const Message& message) {
string serialized_input;
@@ -234,324 +202,276 @@ void TextFormatConformanceTestSuite::RunValidUnknownTextFormatTest(
}
void TextFormatConformanceTestSuite::RunSuiteImpl() {
if (!performance_) {
RunValidTextFormatTest("HelloWorld", REQUIRED,
"optional_string: 'Hello, World!'");
// Integer fields.
RunValidTextFormatTest("Int32FieldMaxValue", REQUIRED,
"optional_int32: 2147483647");
RunValidTextFormatTest("Int32FieldMinValue", REQUIRED,
"optional_int32: -2147483648");
RunValidTextFormatTest("Uint32FieldMaxValue", REQUIRED,
"optional_uint32: 4294967295");
RunValidTextFormatTest("Int64FieldMaxValue", REQUIRED,
"optional_int64: 9223372036854775807");
RunValidTextFormatTest("Int64FieldMinValue", REQUIRED,
"optional_int64: -9223372036854775808");
RunValidTextFormatTest("Uint64FieldMaxValue", REQUIRED,
"optional_uint64: 18446744073709551615");
RunValidTextFormatTest("HelloWorld", REQUIRED,
"optional_string: 'Hello, World!'");
// Integer fields.
RunValidTextFormatTest("Int32FieldMaxValue", REQUIRED,
"optional_int32: 2147483647");
RunValidTextFormatTest("Int32FieldMinValue", REQUIRED,
"optional_int32: -2147483648");
RunValidTextFormatTest("Uint32FieldMaxValue", REQUIRED,
"optional_uint32: 4294967295");
RunValidTextFormatTest("Int64FieldMaxValue", REQUIRED,
"optional_int64: 9223372036854775807");
RunValidTextFormatTest("Int64FieldMinValue", REQUIRED,
"optional_int64: -9223372036854775808");
RunValidTextFormatTest("Uint64FieldMaxValue", REQUIRED,
"optional_uint64: 18446744073709551615");
// Parsers reject out-of-bound integer values.
ExpectParseFailure("Int32FieldTooLarge", REQUIRED,
"optional_int32: 2147483648");
ExpectParseFailure("Int32FieldTooSmall", REQUIRED,
"optional_int32: -2147483649");
ExpectParseFailure("Uint32FieldTooLarge", REQUIRED,
"optional_uint32: 4294967296");
ExpectParseFailure("Int64FieldTooLarge", REQUIRED,
"optional_int64: 9223372036854775808");
ExpectParseFailure("Int64FieldTooSmall", REQUIRED,
"optional_int64: -9223372036854775809");
ExpectParseFailure("Uint64FieldTooLarge", REQUIRED,
"optional_uint64: 18446744073709551616");
// Parsers reject out-of-bound integer values.
ExpectParseFailure("Int32FieldTooLarge", REQUIRED,
"optional_int32: 2147483648");
ExpectParseFailure("Int32FieldTooSmall", REQUIRED,
"optional_int32: -2147483649");
ExpectParseFailure("Uint32FieldTooLarge", REQUIRED,
"optional_uint32: 4294967296");
ExpectParseFailure("Int64FieldTooLarge", REQUIRED,
"optional_int64: 9223372036854775808");
ExpectParseFailure("Int64FieldTooSmall", REQUIRED,
"optional_int64: -9223372036854775809");
ExpectParseFailure("Uint64FieldTooLarge", REQUIRED,
"optional_uint64: 18446744073709551616");
// Floating point fields
RunValidTextFormatTest("FloatField", REQUIRED, "optional_float: 3.192837");
RunValidTextFormatTest("FloatFieldWithVeryPreciseNumber", REQUIRED,
"optional_float: 3.123456789123456789");
RunValidTextFormatTest("FloatFieldMaxValue", REQUIRED,
"optional_float: 3.4028235e+38");
RunValidTextFormatTest("FloatFieldMinValue", REQUIRED,
"optional_float: 1.17549e-38");
RunValidTextFormatTest("FloatFieldNaNValue", REQUIRED,
"optional_float: NaN");
RunValidTextFormatTest("FloatFieldPosInfValue", REQUIRED,
"optional_float: inf");
RunValidTextFormatTest("FloatFieldNegInfValue", REQUIRED,
"optional_float: -inf");
RunValidTextFormatTest("FloatFieldWithInt32Max", REQUIRED,
"optional_float: 4294967296");
RunValidTextFormatTest("FloatFieldLargerThanInt64", REQUIRED,
"optional_float: 9223372036854775808");
RunValidTextFormatTest("FloatFieldTooLarge", REQUIRED,
"optional_float: 3.4028235e+39");
RunValidTextFormatTest("FloatFieldTooSmall", REQUIRED,
"optional_float: 1.17549e-39");
RunValidTextFormatTest("FloatFieldLargerThanUint64", REQUIRED,
"optional_float: 18446744073709551616");
// Floating point fields
RunValidTextFormatTest("FloatField", REQUIRED,
"optional_float: 3.192837");
RunValidTextFormatTest("FloatFieldWithVeryPreciseNumber", REQUIRED,
"optional_float: 3.123456789123456789");
RunValidTextFormatTest("FloatFieldMaxValue", REQUIRED,
"optional_float: 3.4028235e+38");
RunValidTextFormatTest("FloatFieldMinValue", REQUIRED,
"optional_float: 1.17549e-38");
RunValidTextFormatTest("FloatFieldNaNValue", REQUIRED,
"optional_float: NaN");
RunValidTextFormatTest("FloatFieldPosInfValue", REQUIRED,
"optional_float: inf");
RunValidTextFormatTest("FloatFieldNegInfValue", REQUIRED,
"optional_float: -inf");
RunValidTextFormatTest("FloatFieldWithInt32Max", REQUIRED,
"optional_float: 4294967296");
RunValidTextFormatTest("FloatFieldLargerThanInt64", REQUIRED,
"optional_float: 9223372036854775808");
RunValidTextFormatTest("FloatFieldTooLarge", REQUIRED,
"optional_float: 3.4028235e+39");
RunValidTextFormatTest("FloatFieldTooSmall", REQUIRED,
"optional_float: 1.17549e-39");
RunValidTextFormatTest("FloatFieldLargerThanUint64", REQUIRED,
"optional_float: 18446744073709551616");
// String literals x {Strings, Bytes}
for (const auto& field_type : std::vector<std::string>{"String", "Bytes"}) {
const std::string field_name =
field_type == "String" ? "optional_string" : "optional_bytes";
RunValidTextFormatTest(
absl::StrCat("StringLiteralConcat", field_type), REQUIRED,
absl::StrCat(field_name, ": 'first' \"second\"\n'third'"));
RunValidTextFormatTest(
absl::StrCat("StringLiteralBasicEscapes", field_type), REQUIRED,
absl::StrCat(field_name, ": '\\a\\b\\f\\n\\r\\t\\v\\?\\\\\\'\\\"'"));
RunValidTextFormatTest(
absl::StrCat("StringLiteralOctalEscapes", field_type), REQUIRED,
absl::StrCat(field_name, ": '\\341\\210\\264'"));
RunValidTextFormatTest(
absl::StrCat("StringLiteralHexEscapes", field_type), REQUIRED,
absl::StrCat(field_name, ": '\\xe1\\x88\\xb4'"));
RunValidTextFormatTest(
absl::StrCat("StringLiteralShortUnicodeEscape", field_type),
RECOMMENDED, absl::StrCat(field_name, ": '\\u1234'"));
RunValidTextFormatTest(
absl::StrCat("StringLiteralLongUnicodeEscapes", field_type),
RECOMMENDED, absl::StrCat(field_name, ": '\\U00001234\\U00010437'"));
// String literals don't include line feeds.
ExpectParseFailure(
absl::StrCat("StringLiteralIncludesLF", field_type), REQUIRED,
absl::StrCat(field_name, ": 'first line\nsecond line'"));
// Unicode escapes don't include code points that lie beyond the planes
// (> 0x10ffff).
ExpectParseFailure(
absl::StrCat("StringLiteralLongUnicodeEscapeTooLarge", field_type),
REQUIRED, absl::StrCat(field_name, ": '\\U00110000'"));
// Unicode escapes don't include surrogates.
ExpectParseFailure(
absl::StrCat("StringLiteralShortUnicodeEscapeSurrogatePair",
field_type),
RECOMMENDED, absl::StrCat(field_name, ": '\\ud801\\udc37'"));
ExpectParseFailure(
absl::StrCat("StringLiteralShortUnicodeEscapeSurrogateFirstOnly",
field_type),
RECOMMENDED, absl::StrCat(field_name, ": '\\ud800'"));
ExpectParseFailure(
absl::StrCat("StringLiteralShortUnicodeEscapeSurrogateSecondOnly",
field_type),
RECOMMENDED, absl::StrCat(field_name, ": '\\udc00'"));
ExpectParseFailure(
absl::StrCat("StringLiteralLongUnicodeEscapeSurrogateFirstOnly",
field_type),
RECOMMENDED, absl::StrCat(field_name, ": '\\U0000d800'"));
ExpectParseFailure(
absl::StrCat("StringLiteralLongUnicodeEscapeSurrogateSecondOnly",
field_type),
RECOMMENDED, absl::StrCat(field_name, ": '\\U0000dc00'"));
ExpectParseFailure(
absl::StrCat("StringLiteralLongUnicodeEscapeSurrogatePair",
field_type),
RECOMMENDED, absl::StrCat(field_name, ": '\\U0000d801\\U00000dc37'"));
ExpectParseFailure(
absl::StrCat("StringLiteralUnicodeEscapeSurrogatePairLongShort",
field_type),
RECOMMENDED, absl::StrCat(field_name, ": '\\U0000d801\\udc37'"));
ExpectParseFailure(
absl::StrCat("StringLiteralUnicodeEscapeSurrogatePairShortLong",
field_type),
RECOMMENDED, absl::StrCat(field_name, ": '\\ud801\\U0000dc37'"));
// String literals x {Strings, Bytes}
for (const auto& field_type : std::vector<std::string>{"String", "Bytes"}) {
const std::string field_name =
field_type == "String" ? "optional_string" : "optional_bytes";
RunValidTextFormatTest(
StrCat("StringLiteralConcat", field_type), REQUIRED,
StrCat(field_name, ": 'first' \"second\"\n'third'"));
RunValidTextFormatTest(
StrCat("StringLiteralBasicEscapes", field_type), REQUIRED,
StrCat(field_name, ": '\\a\\b\\f\\n\\r\\t\\v\\?\\\\\\'\\\"'"));
RunValidTextFormatTest(
StrCat("StringLiteralOctalEscapes", field_type), REQUIRED,
StrCat(field_name, ": '\\341\\210\\264'"));
RunValidTextFormatTest(StrCat("StringLiteralHexEscapes", field_type),
REQUIRED,
StrCat(field_name, ": '\\xe1\\x88\\xb4'"));
RunValidTextFormatTest(
StrCat("StringLiteralShortUnicodeEscape", field_type),
RECOMMENDED, StrCat(field_name, ": '\\u1234'"));
RunValidTextFormatTest(
StrCat("StringLiteralLongUnicodeEscapes", field_type),
RECOMMENDED, StrCat(field_name, ": '\\U00001234\\U00010437'"));
// String literals don't include line feeds.
ExpectParseFailure(StrCat("StringLiteralIncludesLF", field_type),
REQUIRED,
StrCat(field_name, ": 'first line\nsecond line'"));
// Unicode escapes don't include code points that lie beyond the planes
// (> 0x10ffff).
ExpectParseFailure(
StrCat("StringLiteralLongUnicodeEscapeTooLarge", field_type),
REQUIRED, StrCat(field_name, ": '\\U00110000'"));
// Unicode escapes don't include surrogates.
ExpectParseFailure(
StrCat("StringLiteralShortUnicodeEscapeSurrogatePair",
field_type),
RECOMMENDED, StrCat(field_name, ": '\\ud801\\udc37'"));
ExpectParseFailure(
StrCat("StringLiteralShortUnicodeEscapeSurrogateFirstOnly",
field_type),
RECOMMENDED, StrCat(field_name, ": '\\ud800'"));
ExpectParseFailure(
StrCat("StringLiteralShortUnicodeEscapeSurrogateSecondOnly",
field_type),
RECOMMENDED, StrCat(field_name, ": '\\udc00'"));
ExpectParseFailure(
StrCat("StringLiteralLongUnicodeEscapeSurrogateFirstOnly",
field_type),
RECOMMENDED, StrCat(field_name, ": '\\U0000d800'"));
ExpectParseFailure(
StrCat("StringLiteralLongUnicodeEscapeSurrogateSecondOnly",
field_type),
RECOMMENDED, StrCat(field_name, ": '\\U0000dc00'"));
ExpectParseFailure(
StrCat("StringLiteralLongUnicodeEscapeSurrogatePair", field_type),
RECOMMENDED, StrCat(field_name, ": '\\U0000d801\\U00000dc37'"));
ExpectParseFailure(
StrCat("StringLiteralUnicodeEscapeSurrogatePairLongShort",
field_type),
RECOMMENDED, StrCat(field_name, ": '\\U0000d801\\udc37'"));
ExpectParseFailure(
StrCat("StringLiteralUnicodeEscapeSurrogatePairShortLong",
field_type),
RECOMMENDED, StrCat(field_name, ": '\\ud801\\U0000dc37'"));
// The following method depend on the type of field, as strings have extra
// validation.
const auto test_method =
field_type == "String"
? &TextFormatConformanceTestSuite::ExpectParseFailure
: &TextFormatConformanceTestSuite::RunValidTextFormatTest;
// The following method depend on the type of field, as strings have extra
// validation.
const auto test_method =
field_type == "String"
? &TextFormatConformanceTestSuite::ExpectParseFailure
: &TextFormatConformanceTestSuite::RunValidTextFormatTest;
// String fields reject invalid UTF-8 byte sequences; bytes fields don't.
(this->*test_method)(absl::StrCat(field_type, "FieldBadUTF8Octal"),
REQUIRED, absl::StrCat(field_name, ": '\\300'"));
(this->*test_method)(absl::StrCat(field_type, "FieldBadUTF8Hex"),
REQUIRED, absl::StrCat(field_name, ": '\\xc0'"));
}
// Group fields
RunValidTextFormatTestProto2("GroupFieldNoColon", REQUIRED,
"Data { group_int32: 1 }");
RunValidTextFormatTestProto2("GroupFieldWithColon", REQUIRED,
"Data: { group_int32: 1 }");
RunValidTextFormatTestProto2("GroupFieldEmpty", REQUIRED, "Data {}");
// Unknown Fields
UnknownToTestAllTypes message;
// Unable to print unknown Fixed32/Fixed64 fields as if they are known.
// Fixed32/Fixed64 fields are not added in the tests.
message.set_optional_int32(123);
message.set_optional_string("hello");
message.set_optional_bool(true);
RunValidUnknownTextFormatTest("ScalarUnknownFields", message);
message.Clear();
message.mutable_nested_message()->set_c(111);
RunValidUnknownTextFormatTest("MessageUnknownFields", message);
message.Clear();
message.mutable_optionalgroup()->set_a(321);
RunValidUnknownTextFormatTest("GroupUnknownFields", message);
message.add_repeated_int32(1);
message.add_repeated_int32(2);
message.add_repeated_int32(3);
RunValidUnknownTextFormatTest("RepeatedUnknownFields", message);
// Any fields
RunValidTextFormatTest("AnyField", REQUIRED,
R"(
optional_any: {
[type.googleapis.com/protobuf_test_messages.proto3.TestAllTypesProto3] {
optional_int32: 12345
}
}
)");
RunValidTextFormatTest("AnyFieldWithRawBytes", REQUIRED,
R"(
optional_any: {
type_url: "type.googleapis.com/protobuf_test_messages.proto3.TestAllTypesProto3"
value: "\b\271`"
}
)");
ExpectParseFailure("AnyFieldWithInvalidType", REQUIRED,
R"(
optional_any: {
[type.googleapis.com/unknown] {
optional_int32: 12345
}
}
)");
// Map fields
TestAllTypesProto3 prototype;
(*prototype.mutable_map_string_string())["c"] = "value";
(*prototype.mutable_map_string_string())["b"] = "value";
(*prototype.mutable_map_string_string())["a"] = "value";
RunValidTextFormatTestWithMessage("AlphabeticallySortedMapStringKeys",
REQUIRED,
R"(
map_string_string {
key: "a"
value: "value"
}
map_string_string {
key: "b"
value: "value"
}
map_string_string {
key: "c"
value: "value"
}
)",
prototype);
prototype.Clear();
(*prototype.mutable_map_int32_int32())[3] = 0;
(*prototype.mutable_map_int32_int32())[2] = 0;
(*prototype.mutable_map_int32_int32())[1] = 0;
RunValidTextFormatTestWithMessage("AlphabeticallySortedMapIntKeys",
REQUIRED,
R"(
map_int32_int32 {
key: 1
value: 0
}
map_int32_int32 {
key: 2
value: 0
}
map_int32_int32 {
key: 3
value: 0
}
)",
prototype);
prototype.Clear();
(*prototype.mutable_map_bool_bool())[true] = false;
(*prototype.mutable_map_bool_bool())[false] = false;
RunValidTextFormatTestWithMessage("AlphabeticallySortedMapBoolKeys",
REQUIRED,
R"(
map_bool_bool {
key: false
value: false
}
map_bool_bool {
key: true
value: false
}
)",
prototype);
prototype.Clear();
ConformanceRequestSetting setting_map(
REQUIRED, conformance::TEXT_FORMAT, conformance::PROTOBUF,
conformance::TEXT_FORMAT_TEST, prototype, "DuplicateMapKey", R"(
map_string_nested_message {
key: "duplicate"
value: { a: 123 }
}
map_string_nested_message {
key: "duplicate"
value: { corecursive: {} }
}
)");
// The last-specified value will be retained in a parsed map
RunValidInputTest(setting_map, R"(
map_string_nested_message {
key: "duplicate"
value: { corecursive: {} }
}
)");
}
// Flag control performance tests to keep them internal and opt-in only
if (performance_) {
RunTextFormatPerformanceTests();
}
}
void TextFormatConformanceTestSuite::RunTextFormatPerformanceTests() {
TestTextFormatPerformanceMergeMessageWithRepeatedField("Bool",
"repeated_bool: true");
TestTextFormatPerformanceMergeMessageWithRepeatedField(
"Double", "repeated_double: 123");
TestTextFormatPerformanceMergeMessageWithRepeatedField(
"Int32", "repeated_uint32: 123");
TestTextFormatPerformanceMergeMessageWithRepeatedField(
"Int64", "repeated_uint64: 123");
TestTextFormatPerformanceMergeMessageWithRepeatedField(
"String", R"(repeated_string: "foo")");
TestTextFormatPerformanceMergeMessageWithRepeatedField(
"Bytes", R"(repeated_bytes: "foo")");
}
// This is currently considered valid input by some languages but not others
void TextFormatConformanceTestSuite::
TestTextFormatPerformanceMergeMessageWithRepeatedField(
const string& test_type_name, const string& message_field) {
string recursive_message = "recursive_message { " + message_field + " }";
string input;
for (size_t i = 0; i < kPerformanceRepeatCount; i++) {
input.append(recursive_message);
// String fields reject invalid UTF-8 byte sequences; bytes fields don't.
(this->*test_method)(StrCat(field_type, "FieldBadUTF8Octal"),
REQUIRED, StrCat(field_name, ": '\\300'"));
(this->*test_method)(StrCat(field_type, "FieldBadUTF8Hex"), REQUIRED,
StrCat(field_name, ": '\\xc0'"));
}
string expected = "recursive_message { ";
for (size_t i = 0; i < kPerformanceRepeatCount; i++) {
expected.append(message_field + " ");
}
expected.append("}");
// Group fields
RunValidTextFormatTestProto2("GroupFieldNoColon", REQUIRED,
"Data { group_int32: 1 }");
RunValidTextFormatTestProto2("GroupFieldWithColon", REQUIRED,
"Data: { group_int32: 1 }");
RunValidTextFormatTestProto2("GroupFieldEmpty", REQUIRED,
"Data {}");
RunValidTextFormatTestProto2WithExpected(
"TestTextFormatPerformanceMergeMessageWithRepeatedField" +
test_type_name + "Proto2",
RECOMMENDED, input, expected);
RunValidTextFormatTestWithExpected(
"TestTextFormatPerformanceMergeMessageWithRepeatedField" +
test_type_name + "Proto3",
RECOMMENDED, input, expected);
// Unknown Fields
UnknownToTestAllTypes message;
// Unable to print unknown Fixed32/Fixed64 fields as if they are known.
// Fixed32/Fixed64 fields are not added in the tests.
message.set_optional_int32(123);
message.set_optional_string("hello");
message.set_optional_bool(true);
RunValidUnknownTextFormatTest("ScalarUnknownFields", message);
message.Clear();
message.mutable_nested_message()->set_c(111);
RunValidUnknownTextFormatTest("MessageUnknownFields", message);
message.Clear();
message.mutable_optionalgroup()->set_a(321);
RunValidUnknownTextFormatTest("GroupUnknownFields", message);
message.add_repeated_int32(1);
message.add_repeated_int32(2);
message.add_repeated_int32(3);
RunValidUnknownTextFormatTest("RepeatedUnknownFields", message);
// Any fields
RunValidTextFormatTest("AnyField", REQUIRED,
R"(
optional_any: {
[type.googleapis.com/protobuf_test_messages.proto3.TestAllTypesProto3] {
optional_int32: 12345
}
}
)");
RunValidTextFormatTest("AnyFieldWithRawBytes", REQUIRED,
R"(
optional_any: {
type_url: "type.googleapis.com/protobuf_test_messages.proto3.TestAllTypesProto3"
value: "\b\271`"
}
)");
ExpectParseFailure("AnyFieldWithInvalidType", REQUIRED,
R"(
optional_any: {
[type.googleapis.com/unknown] {
optional_int32: 12345
}
}
)");
// Map fields
TestAllTypesProto3 prototype;
(*prototype.mutable_map_string_string())["c"] = "value";
(*prototype.mutable_map_string_string())["b"] = "value";
(*prototype.mutable_map_string_string())["a"] = "value";
RunValidTextFormatTestWithMessage("AlphabeticallySortedMapStringKeys",
REQUIRED,
R"(
map_string_string {
key: "a"
value: "value"
}
map_string_string {
key: "b"
value: "value"
}
map_string_string {
key: "c"
value: "value"
}
)",
prototype);
prototype.Clear();
(*prototype.mutable_map_int32_int32())[3] = 0;
(*prototype.mutable_map_int32_int32())[2] = 0;
(*prototype.mutable_map_int32_int32())[1] = 0;
RunValidTextFormatTestWithMessage("AlphabeticallySortedMapIntKeys", REQUIRED,
R"(
map_int32_int32 {
key: 1
value: 0
}
map_int32_int32 {
key: 2
value: 0
}
map_int32_int32 {
key: 3
value: 0
}
)",
prototype);
prototype.Clear();
(*prototype.mutable_map_bool_bool())[true] = false;
(*prototype.mutable_map_bool_bool())[false] = false;
RunValidTextFormatTestWithMessage("AlphabeticallySortedMapBoolKeys", REQUIRED,
R"(
map_bool_bool {
key: false
value: false
}
map_bool_bool {
key: true
value: false
}
)",
prototype);
prototype.Clear();
ConformanceRequestSetting setting_map(
REQUIRED, conformance::TEXT_FORMAT, conformance::PROTOBUF,
conformance::TEXT_FORMAT_TEST, prototype, "DuplicateMapKey", R"(
map_string_nested_message {
key: "duplicate"
value: { a: 123 }
}
map_string_nested_message {
key: "duplicate"
value: { corecursive: {} }
}
)");
// The last-specified value will be retained in a parsed map
RunValidInputTest(setting_map, R"(
map_string_nested_message {
key: "duplicate"
value: { corecursive: {} }
}
)");
}
} // namespace protobuf

View File

@@ -42,29 +42,15 @@ class TextFormatConformanceTestSuite : public ConformanceTestSuite {
private:
void RunSuiteImpl() override;
void RunTextFormatPerformanceTests();
void RunValidTextFormatTest(const std::string& test_name,
ConformanceLevel level, const std::string& input);
void RunValidTextFormatTestProto2(const std::string& test_name,
ConformanceLevel level,
const std::string& input);
void RunValidTextFormatTestWithExpected(const std::string& test_name,
ConformanceLevel level,
const std::string& input,
const std::string& expected);
void RunValidTextFormatTestProto2WithExpected(const std::string& test_name,
ConformanceLevel level,
const std::string& input,
const std::string& expected);
void RunValidTextFormatTestWithMessage(const std::string& test_name,
ConformanceLevel level,
const std::string& input_text,
const Message& prototype);
void RunValidTextFormatTestWithMessage(const std::string& test_name,
ConformanceLevel level,
const std::string& input_text,
const std::string& expected_text,
const Message& prototype);
void RunValidUnknownTextFormatTest(const std::string& test_name,
const Message& message);
void ExpectParseFailure(const std::string& test_name, ConformanceLevel level,
@@ -75,8 +61,6 @@ class TextFormatConformanceTestSuite : public ConformanceTestSuite {
bool ParseResponse(const conformance::ConformanceResponse& response,
const ConformanceRequestSetting& setting,
Message* test_message) override;
void TestTextFormatPerformanceMergeMessageWithRepeatedField(
const std::string& test_type_name, const std::string& message_field);
};
} // namespace protobuf

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff