chore(php): conformance testing for edition (#16712)
COPYBARA_INTEGRATE_REVIEW=https://github.com/protocolbuffers/protobuf/pull/16712 from bshaffer:php-editions a1c41add7d
PiperOrigin-RevId: 631824623
pull/16762/head
parent
b77343aa2c
commit
01744cccae
|
@ -332,13 +332,14 @@ inline_sh_binary(
|
|||
],
|
||||
cmd = """
|
||||
php -dextension=$(rootpath //php:extension) \\
|
||||
-d include_path=conformance:src/google/protobuf \\
|
||||
-d include_path=conformance:src/google/protobuf:editions/golden \\
|
||||
$(rootpath conformance_php.php)
|
||||
""",
|
||||
visibility = ["//php:__subpackages__"],
|
||||
deps = [
|
||||
":conformance_php_proto",
|
||||
"//:test_messages_proto3_php_proto",
|
||||
"//editions:test_messages_proto3_editions_php_proto",
|
||||
],
|
||||
)
|
||||
|
||||
|
|
|
@ -1,80 +1,134 @@
|
|||
<?php
|
||||
|
||||
require_once("Conformance/WireFormat.php");
|
||||
require_once("Conformance/ConformanceResponse.php");
|
||||
require_once("Conformance/ConformanceRequest.php");
|
||||
require_once("Conformance/FailureSet.php");
|
||||
require_once("Conformance/JspbEncodingConfig.php");
|
||||
require_once("Conformance/TestCategory.php");
|
||||
require_once("Protobuf_test_messages/Proto3/ForeignMessage.php");
|
||||
require_once("Protobuf_test_messages/Proto3/ForeignEnum.php");
|
||||
require_once("Protobuf_test_messages/Proto3/TestAllTypesProto3.php");
|
||||
require_once("Protobuf_test_messages/Proto3/TestAllTypesProto3/AliasedEnum.php");
|
||||
require_once("Protobuf_test_messages/Proto3/TestAllTypesProto3/NestedMessage.php");
|
||||
require_once("Protobuf_test_messages/Proto3/TestAllTypesProto3/NestedEnum.php");
|
||||
require_once('Conformance/WireFormat.php');
|
||||
require_once('Conformance/ConformanceResponse.php');
|
||||
require_once('Conformance/ConformanceRequest.php');
|
||||
require_once('Conformance/FailureSet.php');
|
||||
require_once('Conformance/JspbEncodingConfig.php');
|
||||
require_once('Conformance/TestCategory.php');
|
||||
require_once('Protobuf_test_messages/Proto3/ForeignMessage.php');
|
||||
require_once('Protobuf_test_messages/Proto3/ForeignEnum.php');
|
||||
require_once('Protobuf_test_messages/Proto3/TestAllTypesProto3.php');
|
||||
require_once('Protobuf_test_messages/Proto3/TestAllTypesProto3/AliasedEnum.php');
|
||||
require_once('Protobuf_test_messages/Proto3/TestAllTypesProto3/NestedMessage.php');
|
||||
require_once('Protobuf_test_messages/Proto3/TestAllTypesProto3/NestedEnum.php');
|
||||
require_once('Protobuf_test_messages/Editions/Proto3/EnumOnlyProto3/PBBool.php');
|
||||
require_once('Protobuf_test_messages/Editions/Proto3/EnumOnlyProto3.php');
|
||||
require_once('Protobuf_test_messages/Editions/Proto3/TestAllTypesProto3/NestedMessage.php');
|
||||
require_once('Protobuf_test_messages/Editions/Proto3/TestAllTypesProto3/NestedEnum.php');
|
||||
require_once('Protobuf_test_messages/Editions/Proto3/TestAllTypesProto3/AliasedEnum.php');
|
||||
require_once('Protobuf_test_messages/Editions/Proto3/TestAllTypesProto3.php');
|
||||
require_once('Protobuf_test_messages/Editions/Proto3/NullHypothesisProto3.php');
|
||||
require_once('Protobuf_test_messages/Editions/Proto3/ForeignEnum.php');
|
||||
require_once('Protobuf_test_messages/Editions/Proto3/ForeignMessage.php');
|
||||
require_once('GPBMetadata/Conformance.php');
|
||||
require_once('GPBMetadata/TestMessagesProto3.php');
|
||||
require_once('GPBMetadata/TestMessagesProto3Editions.php');
|
||||
|
||||
require_once("GPBMetadata/Conformance.php");
|
||||
require_once("GPBMetadata/TestMessagesProto3.php");
|
||||
use Conformance\ConformanceRequest;
|
||||
use Conformance\ConformanceResponse;
|
||||
use Conformance\TestCategory;
|
||||
use Conformance\WireFormat;
|
||||
use Protobuf_test_messages\Proto3\TestAllTypesProto3;
|
||||
use Protobuf_test_messages\Editions\Proto3\TestAllTypesProto3 as TestAllTypesProto3Editions;
|
||||
|
||||
use \Conformance\TestCategory;
|
||||
use \Conformance\WireFormat;
|
||||
|
||||
if (!ini_get("date.timezone")) {
|
||||
ini_set("date.timezone", "UTC");
|
||||
if (!ini_get('date.timezone')) {
|
||||
ini_set('date.timezone', 'UTC');
|
||||
}
|
||||
|
||||
$test_count = 0;
|
||||
|
||||
function doTest($request)
|
||||
{
|
||||
$test_message = new \Protobuf_test_messages\Proto3\TestAllTypesProto3();
|
||||
$response = new \Conformance\ConformanceResponse();
|
||||
if ($request->getPayload() == "protobuf_payload") {
|
||||
if ($request->getMessageType() == "conformance.FailureSet") {
|
||||
$response->setProtobufPayload("");
|
||||
return $response;
|
||||
} elseif ($request->getMessageType() == "protobuf_test_messages.proto3.TestAllTypesProto3") {
|
||||
try {
|
||||
$test_message->mergeFromString($request->getProtobufPayload());
|
||||
} catch (Exception $e) {
|
||||
$response->setParseError($e->getMessage());
|
||||
return $response;
|
||||
}
|
||||
} elseif ($request->getMessageType() == "protobuf_test_messages.proto2.TestAllTypesProto2") {
|
||||
$response->setSkipped("PHP doesn't support proto2");
|
||||
return $response;
|
||||
} else {
|
||||
trigger_error("Protobuf request doesn't have specific payload type", E_USER_ERROR);
|
||||
}
|
||||
} elseif ($request->getPayload() == "json_payload") {
|
||||
$ignore_json_unknown =
|
||||
($request->getTestCategory() ==
|
||||
TestCategory::JSON_IGNORE_UNKNOWN_PARSING_TEST);
|
||||
try {
|
||||
$test_message->mergeFromJsonString($request->getJsonPayload(),
|
||||
$ignore_json_unknown);
|
||||
} catch (Exception $e) {
|
||||
$response->setParseError($e->getMessage());
|
||||
return $response;
|
||||
}
|
||||
} elseif ($request->getPayload() == "text_payload") {
|
||||
$response->setSkipped("PHP doesn't support text format yet");
|
||||
return $response;
|
||||
} else {
|
||||
trigger_error("Request didn't have payload.", E_USER_ERROR);
|
||||
$response = new ConformanceResponse();
|
||||
|
||||
switch ($request->getPayload()) {
|
||||
case 'protobuf_payload':
|
||||
switch ($request->getMessageType()) {
|
||||
case 'protobuf_test_messages.proto3.TestAllTypesProto3':
|
||||
$test_message = new TestAllTypesProto3();
|
||||
break;
|
||||
case 'protobuf_test_messages.editions.proto3.TestAllTypesProto3':
|
||||
$test_message = new TestAllTypesProto3Editions();
|
||||
break;
|
||||
case 'conformance.FailureSet':
|
||||
$response->setProtobufPayload('');
|
||||
return $response;
|
||||
case 'protobuf_test_messages.proto2.TestAllTypesProto2':
|
||||
case 'protobuf_test_messages.editions.proto2.TestAllTypesProto2':
|
||||
$response->setSkipped('PHP doesn\'t support proto2');
|
||||
return $response;
|
||||
case 'protobuf_test_messages.editions.TestAllTypesEdition2023':
|
||||
$response->setSkipped('PHP doesn\'t support editions-specific features yet');
|
||||
return $response;
|
||||
case '':
|
||||
trigger_error(
|
||||
'Protobuf request doesn\'t have specific payload type',
|
||||
E_USER_ERROR
|
||||
);
|
||||
default:
|
||||
trigger_error(sprintf(
|
||||
'Protobuf request doesn\'t support %s message type',
|
||||
$request->getMessageType(),
|
||||
), E_USER_ERROR);
|
||||
}
|
||||
|
||||
try {
|
||||
$test_message->mergeFromString($request->getProtobufPayload());
|
||||
} catch (Exception $e) {
|
||||
$response->setParseError($e->getMessage());
|
||||
return $response;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'json_payload':
|
||||
switch ($request->getMessageType()) {
|
||||
case 'protobuf_test_messages.editions.proto3.TestAllTypesProto3':
|
||||
$test_message = new TestAllTypesProto3Editions();
|
||||
break;
|
||||
case 'protobuf_test_messages.editions.proto2.TestAllTypesProto2':
|
||||
$response->setSkipped('PHP doesn\'t support proto2');
|
||||
return $response;
|
||||
default:
|
||||
$test_message = new TestAllTypesProto3();
|
||||
}
|
||||
|
||||
$ignore_json_unknown =
|
||||
($request->getTestCategory() == TestCategory::JSON_IGNORE_UNKNOWN_PARSING_TEST);
|
||||
try {
|
||||
$test_message->mergeFromJsonString(
|
||||
$request->getJsonPayload(),
|
||||
$ignore_json_unknown
|
||||
);
|
||||
} catch (Exception $e) {
|
||||
$response->setParseError($e->getMessage());
|
||||
return $response;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'text_payload':
|
||||
$response->setSkipped('PHP doesn\'t support text format yet');
|
||||
return $response;
|
||||
default:
|
||||
trigger_error('Request didn\'t have payload.', E_USER_ERROR);
|
||||
}
|
||||
|
||||
if ($request->getRequestedOutputFormat() == WireFormat::UNSPECIFIED) {
|
||||
trigger_error("Unspecified output format.", E_USER_ERROR);
|
||||
} elseif ($request->getRequestedOutputFormat() == WireFormat::PROTOBUF) {
|
||||
$response->setProtobufPayload($test_message->serializeToString());
|
||||
} elseif ($request->getRequestedOutputFormat() == WireFormat::JSON) {
|
||||
try {
|
||||
$response->setJsonPayload($test_message->serializeToJsonString());
|
||||
} catch (Exception $e) {
|
||||
$response->setSerializeError($e->getMessage());
|
||||
return $response;
|
||||
}
|
||||
switch ($request->getRequestedOutputFormat()) {
|
||||
case WireFormat::TEXT_FORMAT:
|
||||
$response->setSkipped('PHP doesn\'t support text format yet');
|
||||
return $response;
|
||||
case WireFormat::UNSPECIFIED:
|
||||
trigger_error('Unspecified output format.', E_USER_ERROR);
|
||||
case WireFormat::PROTOBUF:
|
||||
$response->setProtobufPayload($test_message->serializeToString());
|
||||
break;
|
||||
case WireFormat::JSON:
|
||||
try {
|
||||
$response->setJsonPayload($test_message->serializeToJsonString());
|
||||
} catch (Exception $e) {
|
||||
$response->setSerializeError($e->getMessage());
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
||||
return $response;
|
||||
|
@ -84,25 +138,25 @@ function doTestIO()
|
|||
{
|
||||
$length_bytes = fread(STDIN, 4);
|
||||
if (strlen($length_bytes) == 0) {
|
||||
return false; # EOF
|
||||
return false; # EOF
|
||||
} elseif (strlen($length_bytes) != 4) {
|
||||
fwrite(STDERR, "I/O error\n");
|
||||
return false;
|
||||
fwrite(STDERR, "I/O error\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
$length = unpack("V", $length_bytes)[1];
|
||||
$length = unpack('V', $length_bytes)[1];
|
||||
$serialized_request = fread(STDIN, $length);
|
||||
if (strlen($serialized_request) != $length) {
|
||||
trigger_error("I/O error", E_USER_ERROR);
|
||||
trigger_error('I/O error', E_USER_ERROR);
|
||||
}
|
||||
|
||||
$request = new \Conformance\ConformanceRequest();
|
||||
$request = new ConformanceRequest();
|
||||
$request->mergeFromString($serialized_request);
|
||||
|
||||
$response = doTest($request);
|
||||
|
||||
$serialized_response = $response->serializeToString();
|
||||
fwrite(STDOUT, pack("V", strlen($serialized_response)));
|
||||
fwrite(STDOUT, pack('V', strlen($serialized_response)));
|
||||
fwrite(STDOUT, $serialized_response);
|
||||
|
||||
$GLOBALS['test_count'] += 1;
|
||||
|
@ -111,10 +165,10 @@ function doTestIO()
|
|||
}
|
||||
|
||||
while(true){
|
||||
if (!doTestIO()) {
|
||||
fprintf(STDERR,
|
||||
"conformance_php: received EOF from test runner " .
|
||||
"after %d tests, exiting\n", $test_count);
|
||||
exit;
|
||||
}
|
||||
if (!doTestIO()) {
|
||||
fprintf(STDERR,
|
||||
'conformance_php: received EOF from test runner ' .
|
||||
"after %d tests, exiting\n", $test_count);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
Recommended.Proto3.ProtobufInput.GroupUnknownFields_Drop.TextFormatOutput
|
||||
Recommended.Proto3.ProtobufInput.GroupUnknownFields_Print.TextFormatOutput
|
||||
Recommended.Proto3.ProtobufInput.MessageUnknownFields_Drop.TextFormatOutput
|
||||
Recommended.Proto3.ProtobufInput.MessageUnknownFields_Print.TextFormatOutput
|
||||
Recommended.Proto3.ProtobufInput.RepeatedUnknownFields_Drop.TextFormatOutput
|
||||
Recommended.Proto3.ProtobufInput.RepeatedUnknownFields_Print.TextFormatOutput
|
||||
Recommended.Proto3.ProtobufInput.ScalarUnknownFields_Drop.TextFormatOutput
|
||||
Recommended.Proto3.ProtobufInput.ScalarUnknownFields_Print.TextFormatOutput
|
|
@ -1,5 +1,5 @@
|
|||
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
|
||||
load("//:protobuf.bzl", "internal_objc_proto_library", "internal_py_proto_library")
|
||||
load("//:protobuf.bzl", "internal_objc_proto_library", "internal_php_proto_library", "internal_py_proto_library")
|
||||
load("//bazel:cc_proto_library.bzl", "cc_proto_library")
|
||||
load("//bazel:upb_proto_library.bzl", "upb_c_proto_library", "upb_proto_reflection_library")
|
||||
load(":defaults.bzl", "compile_edition_defaults", "embed_edition_defaults")
|
||||
|
@ -236,6 +236,31 @@ java_lite_proto_library(
|
|||
deps = [":test_messages_proto3_editions_proto"],
|
||||
)
|
||||
|
||||
internal_php_proto_library(
|
||||
name = "test_messages_proto3_editions_php_proto",
|
||||
testonly = 1,
|
||||
srcs = ["golden/test_messages_proto3_editions.proto"],
|
||||
outs = [
|
||||
"GPBMetadata/TestMessagesProto3Editions.php",
|
||||
"Protobuf_test_messages/Editions/Proto3/EnumOnlyProto3.php",
|
||||
"Protobuf_test_messages/Editions/Proto3/EnumOnlyProto3/PBBool.php",
|
||||
"Protobuf_test_messages/Editions/Proto3/ForeignEnum.php",
|
||||
"Protobuf_test_messages/Editions/Proto3/ForeignMessage.php",
|
||||
"Protobuf_test_messages/Editions/Proto3/NullHypothesisProto3.php",
|
||||
"Protobuf_test_messages/Editions/Proto3/TestAllTypesProto3.php",
|
||||
"Protobuf_test_messages/Editions/Proto3/TestAllTypesProto3/AliasedEnum.php",
|
||||
"Protobuf_test_messages/Editions/Proto3/TestAllTypesProto3/NestedEnum.php",
|
||||
"Protobuf_test_messages/Editions/Proto3/TestAllTypesProto3/NestedMessage.php",
|
||||
],
|
||||
enable_editions = True,
|
||||
includes = [
|
||||
"golden",
|
||||
"src",
|
||||
],
|
||||
proto_deps = ["//:well_known_protos"],
|
||||
visibility = ["//conformance:__pkg__"],
|
||||
)
|
||||
|
||||
internal_py_proto_library(
|
||||
name = "test_messages_proto3_editions_py_pb2",
|
||||
testonly = True,
|
||||
|
|
|
@ -64,6 +64,7 @@ genrule(
|
|||
conformance_test(
|
||||
name = "conformance_test",
|
||||
failure_list = "//conformance:failure_list_php.txt",
|
||||
maximum_edition = "2023",
|
||||
target_compatible_with = select({
|
||||
"@platforms//os:osx": ["@platforms//:incompatible"],
|
||||
"//conditions:default": [],
|
||||
|
@ -75,6 +76,7 @@ conformance_test(
|
|||
conformance_test(
|
||||
name = "conformance_test_c",
|
||||
failure_list = "//conformance:failure_list_php_c.txt",
|
||||
maximum_edition = "2023",
|
||||
target_compatible_with = select({
|
||||
"@platforms//os:osx": [],
|
||||
"//conditions:default": ["@platforms//:incompatible"],
|
||||
|
|
|
@ -80,6 +80,7 @@ def _proto_gen_impl(ctx):
|
|||
srcs = ctx.files.srcs
|
||||
langs = ctx.attr.langs or []
|
||||
out_type = ctx.attr.out_type
|
||||
enable_editions = ctx.attr.enable_editions
|
||||
deps = depset(direct = ctx.files.srcs)
|
||||
source_dir = _SourceDir(ctx)
|
||||
gen_dir = _GenDir(ctx).rstrip("/")
|
||||
|
@ -130,6 +131,8 @@ def _proto_gen_impl(ctx):
|
|||
generated_files = []
|
||||
for src in srcs:
|
||||
args = []
|
||||
if enable_editions:
|
||||
args.append("--experimental_editions")
|
||||
|
||||
in_gen_dir = src.root.path == gen_dir
|
||||
if in_gen_dir:
|
||||
|
@ -231,6 +234,7 @@ Args:
|
|||
srcs: Protocol Buffers definition files (.proto) to run the protocol compiler
|
||||
against.
|
||||
deps: a list of dependency labels; must be other proto libraries.
|
||||
enable_editions: if true, sets the --experimental_editions flag.
|
||||
includes: a list of include paths to .proto files.
|
||||
protoc: the label of the protocol compiler to generate the sources.
|
||||
plugin: the label of the protocol compiler plugin to be passed to the protocol
|
||||
|
@ -247,6 +251,7 @@ _proto_gen = rule(
|
|||
attrs = {
|
||||
"srcs": attr.label_list(allow_files = True),
|
||||
"deps": attr.label_list(providers = [ProtoGenInfo]),
|
||||
"enable_editions": attr.bool(),
|
||||
"includes": attr.string_list(),
|
||||
"protoc": attr.label(
|
||||
cfg = "exec",
|
||||
|
@ -655,6 +660,7 @@ def _source_proto_library(
|
|||
protoc = Label("//:protoc"),
|
||||
testonly = None,
|
||||
visibility = ["//visibility:public"],
|
||||
enable_editions = False,
|
||||
**kwargs):
|
||||
"""Bazel rule to create generated protobuf code from proto source files for
|
||||
languages not well supported by Bazel yet. This will output the generated
|
||||
|
@ -699,6 +705,7 @@ def _source_proto_library(
|
|||
srcs = proto_deps,
|
||||
protoc = protoc,
|
||||
includes = includes,
|
||||
enable_editions = enable_editions,
|
||||
)
|
||||
full_deps.append(":%s_deps_genproto" % name)
|
||||
|
||||
|
@ -712,6 +719,7 @@ def _source_proto_library(
|
|||
protoc = protoc,
|
||||
testonly = testonly,
|
||||
visibility = visibility,
|
||||
enable_editions = enable_editions,
|
||||
)
|
||||
|
||||
native.filegroup(
|
||||
|
|
|
@ -37,7 +37,13 @@ class PROTOC_EXPORT Generator : public CodeGenerator {
|
|||
std::string* error) const override;
|
||||
|
||||
uint64_t GetSupportedFeatures() const override {
|
||||
return FEATURE_PROTO3_OPTIONAL;
|
||||
return Feature::FEATURE_PROTO3_OPTIONAL;
|
||||
}
|
||||
|
||||
Edition GetMinimumEdition() const override { return Edition::EDITION_PROTO2; }
|
||||
Edition GetMaximumEdition() const override { return Edition::EDITION_2023; }
|
||||
std::vector<const FieldDescriptor*> GetFeatureExtensions() const override {
|
||||
return {};
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
Loading…
Reference in New Issue