Down-integrate internal changes to github. (#5555)
* Down-integrate internal changes to github.
* fix python conformance test
* fix csharp conformance test
* add back java map_lite_test.proto's optimize for option
* fix php conformance test
diff --git a/conformance/Makefile.am b/conformance/Makefile.am
index 8f30124..f45bfe3 100644
--- a/conformance/Makefile.am
+++ b/conformance/Makefile.am
@@ -107,6 +107,7 @@
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 \
diff --git a/conformance/conformance.proto b/conformance/conformance.proto
index b0dc762..91e2ad3 100644
--- a/conformance/conformance.proto
+++ b/conformance/conformance.proto
@@ -61,7 +61,7 @@
enum TestCategory {
UNSPECIFIED_TEST = 0;
BINARY_TEST = 1; // Test binary wire format.
- JSON_TEST = 2; // Test json wire format.
+ JSON_TEST = 2; // Test json wire format.
// Similar to JSON_TEST. However, during parsing json, testee should ignore
// unknown fields. This feature is optional. Each implementation can descide
// whether to support it. See
@@ -72,6 +72,10 @@
// Opensource testees just skip it.
}
+message FailureSet {
+ repeated string failure = 1;
+}
+
// Represents a single test case's input. The testee should:
//
// 1. parse this proto (which should always succeed)
diff --git a/conformance/conformance_cpp.cc b/conformance/conformance_cpp.cc
index ce333ee..a451ab0 100644
--- a/conformance/conformance_cpp.cc
+++ b/conformance/conformance_cpp.cc
@@ -57,6 +57,35 @@
static const char kTypeUrlPrefix[] = "type.googleapis.com";
+const char* kFailures[] = {
+#if !GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+ "Required.Proto2.ProtobufInput."
+ "PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE",
+ "Required.Proto2.ProtobufInput."
+ "PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE",
+ "Required.Proto2.ProtobufInput.PrematureEofInPackedField.BOOL",
+ "Required.Proto2.ProtobufInput.PrematureEofInPackedField.ENUM",
+ "Required.Proto2.ProtobufInput.PrematureEofInPackedField.INT32",
+ "Required.Proto2.ProtobufInput.PrematureEofInPackedField.INT64",
+ "Required.Proto2.ProtobufInput.PrematureEofInPackedField.SINT32",
+ "Required.Proto2.ProtobufInput.PrematureEofInPackedField.SINT64",
+ "Required.Proto2.ProtobufInput.PrematureEofInPackedField.UINT32",
+ "Required.Proto2.ProtobufInput.PrematureEofInPackedField.UINT64",
+ "Required.Proto3.ProtobufInput."
+ "PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE",
+ "Required.Proto3.ProtobufInput."
+ "PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE",
+ "Required.Proto3.ProtobufInput.PrematureEofInPackedField.BOOL",
+ "Required.Proto3.ProtobufInput.PrematureEofInPackedField.ENUM",
+ "Required.Proto3.ProtobufInput.PrematureEofInPackedField.INT32",
+ "Required.Proto3.ProtobufInput.PrematureEofInPackedField.INT64",
+ "Required.Proto3.ProtobufInput.PrematureEofInPackedField.SINT32",
+ "Required.Proto3.ProtobufInput.PrematureEofInPackedField.SINT64",
+ "Required.Proto3.ProtobufInput.PrematureEofInPackedField.UINT32",
+ "Required.Proto3.ProtobufInput.PrematureEofInPackedField.UINT64",
+#endif
+};
+
static string GetTypeUrl(const Descriptor* message) {
return string(kTypeUrlPrefix) + "/" + message->full_name();
}
@@ -144,6 +173,12 @@
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:
GOOGLE_LOG(FATAL) << "Unspecified output format";
diff --git a/conformance/conformance_php.php b/conformance/conformance_php.php
index 80860c9..2eeaa63 100755
--- a/conformance/conformance_php.php
+++ b/conformance/conformance_php.php
@@ -3,6 +3,7 @@
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");
@@ -29,7 +30,10 @@
$test_message = new \Protobuf_test_messages\Proto3\TestAllTypesProto3();
$response = new \Conformance\ConformanceResponse();
if ($request->getPayload() == "protobuf_payload") {
- if ($request->getMessageType() == "protobuf_test_messages.proto3.TestAllTypesProto3") {
+ 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) {
diff --git a/conformance/conformance_python.py b/conformance/conformance_python.py
index 876642b..f1975e0 100755
--- a/conformance/conformance_python.py
+++ b/conformance/conformance_python.py
@@ -56,26 +56,75 @@
pass
def do_test(request):
+ response = conformance_pb2.ConformanceResponse()
+
+ if request.message_type == "conformance.FailureSet":
+ failure_set = conformance_pb2.FailureSet()
+ failures = []
+ # TODO(gerbens): Remove, this is a hack to detect if the old vs new
+ # parser is used by the cpp code. Relying on a bug in the old parser.
+ hack_proto = test_messages_proto2_pb2.TestAllTypesProto2()
+ if hack_proto.ParseFromString(b"\322\002\001"):
+ # the string above is one of the failing conformance test strings of the
+ # old parser. If we succeed the c++ implementation is using the old
+ # parser so we add the list of failing conformance tests.
+ failures = [
+ "Required.Proto3.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE",
+ "Required.Proto3.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE",
+ "Required.Proto3.ProtobufInput.PrematureEofInPackedField.BOOL",
+ "Required.Proto3.ProtobufInput.PrematureEofInPackedField.DOUBLE",
+ "Required.Proto3.ProtobufInput.PrematureEofInPackedField.ENUM",
+ "Required.Proto3.ProtobufInput.PrematureEofInPackedField.FIXED32",
+ "Required.Proto3.ProtobufInput.PrematureEofInPackedField.FIXED64",
+ "Required.Proto3.ProtobufInput.PrematureEofInPackedField.FLOAT",
+ "Required.Proto3.ProtobufInput.PrematureEofInPackedField.INT32",
+ "Required.Proto3.ProtobufInput.PrematureEofInPackedField.INT64",
+ "Required.Proto3.ProtobufInput.PrematureEofInPackedField.SFIXED32",
+ "Required.Proto3.ProtobufInput.PrematureEofInPackedField.SFIXED64",
+ "Required.Proto3.ProtobufInput.PrematureEofInPackedField.SINT32",
+ "Required.Proto3.ProtobufInput.PrematureEofInPackedField.SINT64",
+ "Required.Proto3.ProtobufInput.PrematureEofInPackedField.UINT32",
+ "Required.Proto3.ProtobufInput.PrematureEofInPackedField.UINT64",
+ "Required.Proto2.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE",
+ "Required.Proto2.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE",
+ "Required.Proto2.ProtobufInput.PrematureEofInPackedField.BOOL",
+ "Required.Proto2.ProtobufInput.PrematureEofInPackedField.DOUBLE",
+ "Required.Proto2.ProtobufInput.PrematureEofInPackedField.ENUM",
+ "Required.Proto2.ProtobufInput.PrematureEofInPackedField.FIXED32",
+ "Required.Proto2.ProtobufInput.PrematureEofInPackedField.FIXED64",
+ "Required.Proto2.ProtobufInput.PrematureEofInPackedField.FLOAT",
+ "Required.Proto2.ProtobufInput.PrematureEofInPackedField.INT32",
+ "Required.Proto2.ProtobufInput.PrematureEofInPackedField.INT64",
+ "Required.Proto2.ProtobufInput.PrematureEofInPackedField.SFIXED32",
+ "Required.Proto2.ProtobufInput.PrematureEofInPackedField.SFIXED64",
+ "Required.Proto2.ProtobufInput.PrematureEofInPackedField.SINT32",
+ "Required.Proto2.ProtobufInput.PrematureEofInPackedField.SINT64",
+ "Required.Proto2.ProtobufInput.PrematureEofInPackedField.UINT32",
+ "Required.Proto2.ProtobufInput.PrematureEofInPackedField.UINT64",
+ ]
+ for x in failures:
+ failure_set.failure.append(x)
+ response.protobuf_payload = failure_set.SerializeToString()
+ return response
+
isProto3 = (request.message_type == "protobuf_test_messages.proto3.TestAllTypesProto3")
isJson = (request.WhichOneof('payload') == 'json_payload')
isProto2 = (request.message_type == "protobuf_test_messages.proto2.TestAllTypesProto2")
-
+
if (not isProto3) and (not isJson) and (not isProto2):
raise ProtocolError("Protobuf request doesn't have specific payload type")
-
+
test_message = test_messages_proto2_pb2.TestAllTypesProto2() if isProto2 else \
test_messages_proto3_pb2.TestAllTypesProto3()
- response = conformance_pb2.ConformanceResponse()
-
try:
if request.WhichOneof('payload') == 'protobuf_payload':
try:
test_message.ParseFromString(request.protobuf_payload)
except message.DecodeError as e:
response.parse_error = str(e)
- return response
-
+ return response
+
elif request.WhichOneof('payload') == 'json_payload':
try:
ignore_unknown_fields = \
@@ -97,7 +146,7 @@
response.protobuf_payload = test_message.SerializeToString()
elif request.requested_output_format == conformance_pb2.JSON:
- try:
+ try:
response.json_payload = json_format.MessageToJson(test_message)
except Exception as e:
response.serialize_error = str(e)
diff --git a/conformance/conformance_test.cc b/conformance/conformance_test.cc
index 68b813d..265a053 100644
--- a/conformance/conformance_test.cc
+++ b/conformance/conformance_test.cc
@@ -150,15 +150,6 @@
return "";
}
-void ConformanceTestSuite::SetFailureList(
- const string& filename,
- const std::vector<string>& failure_list) {
- failure_list_filename_ = filename;
- expected_to_fail_.clear();
- std::copy(failure_list.begin(), failure_list.end(),
- std::inserter(expected_to_fail_, expected_to_fail_.end()));
-}
-
void ConformanceTestSuite::ReportSuccess(const string& test_name) {
if (expected_to_fail_.erase(test_name) != 0) {
StringAppendF(&output_,
@@ -359,8 +350,9 @@
return "";
}
-bool ConformanceTestSuite::RunSuite(
- ConformanceTestRunner* runner, std::string* output) {
+bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner,
+ std::string* output, const string& filename,
+ conformance::FailureSet* failure_list) {
runner_ = runner;
successes_ = 0;
expected_failures_ = 0;
@@ -371,6 +363,18 @@
output_ = "\nCONFORMANCE TEST BEGIN ====================================\n\n";
+ ConformanceRequest req;
+ ConformanceResponse res;
+ req.set_message_type(failure_list->GetTypeName());
+ req.set_protobuf_payload("");
+ req.set_requested_output_format(conformance::WireFormat::PROTOBUF);
+ RunTest("FindFailures", req, &res);
+ GOOGLE_CHECK(failure_list->MergeFromString(res.protobuf_payload()));
+ failure_list_filename_ = filename;
+ expected_to_fail_.clear();
+ for (const string& failure : failure_list->failure()) {
+ expected_to_fail_.insert(failure);
+ }
RunSuiteImpl();
bool ok = true;
diff --git a/conformance/conformance_test.h b/conformance/conformance_test.h
index ab82bbe..e0bc1e0 100644
--- a/conformance/conformance_test.h
+++ b/conformance/conformance_test.h
@@ -144,15 +144,6 @@
void SetVerbose(bool verbose) { verbose_ = verbose; }
- // Sets the list of tests that are expected to fail when RunSuite() is called.
- // RunSuite() will fail unless the set of failing tests is exactly the same
- // as this list.
- //
- // The filename here is *only* used to create/format useful error messages for
- // how to update the failure list. We do NOT read this file at all.
- void SetFailureList(const std::string& filename,
- const std::vector<std::string>& failure_list);
-
// Whether to require the testee to pass RECOMMENDED tests. By default failing
// a RECOMMENDED test case will not fail the entire suite but will only
// generated a warning. If this flag is set to true, RECOMMENDED tests will
@@ -169,9 +160,12 @@
// Test output will be stored in "output".
//
// Returns true if the set of failing tests was exactly the same as the
- // failure list. If SetFailureList() was not called, returns true if all
- // tests passed.
- bool RunSuite(ConformanceTestRunner* runner, std::string* output);
+ // failure list.
+ // The filename here is *only* used to create/format useful error messages for
+ // how to update the failure list. We do NOT read this file at all.
+ bool RunSuite(ConformanceTestRunner* runner, std::string* output,
+ const std::string& filename,
+ conformance::FailureSet* failure_list);
protected:
// Test cases are classified into a few categories:
diff --git a/conformance/conformance_test_runner.cc b/conformance/conformance_test_runner.cc
index 8b44752..0279bb6 100644
--- a/conformance/conformance_test_runner.cc
+++ b/conformance/conformance_test_runner.cc
@@ -84,7 +84,7 @@
namespace protobuf {
void ParseFailureList(const char *filename,
- std::vector<string>* failure_list) {
+ conformance::FailureSet *failure_list) {
std::ifstream infile(filename);
if (!infile.is_open()) {
@@ -101,7 +101,7 @@
line = line.substr(0, line.find("#"));
if (!line.empty()) {
- failure_list->push_back(line);
+ failure_list->add_failure(line);
}
}
}
@@ -178,7 +178,7 @@
int argc, char *argv[], ConformanceTestSuite* suite) {
char *program;
string failure_list_filename;
- std::vector<string> failure_list;
+ conformance::FailureSet failure_list;
for (int arg = 1; arg < argc; ++arg) {
if (strcmp(argv[arg], "--failure_list") == 0) {
@@ -201,11 +201,11 @@
}
}
- suite->SetFailureList(failure_list_filename, failure_list);
ForkPipeRunner runner(program);
std::string output;
- bool ok = suite->RunSuite(&runner, &output);
+ bool ok =
+ suite->RunSuite(&runner, &output, failure_list_filename, &failure_list);
fwrite(output.c_str(), 1, output.size(), stderr);
diff --git a/conformance/failure_list_cpp.txt b/conformance/failure_list_cpp.txt
index 752fbb5..0c01e1e 100644
--- a/conformance/failure_list_cpp.txt
+++ b/conformance/failure_list_cpp.txt
@@ -34,23 +34,3 @@
Recommended.Proto3.JsonInput.TrailingCommaInAnObjectWithNewlines
Recommended.Proto3.JsonInput.TrailingCommaInAnObjectWithSpace
Recommended.Proto3.JsonInput.TrailingCommaInAnObjectWithSpaceCommaSpace
-Required.Proto3.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE
-Required.Proto3.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE
-Required.Proto3.ProtobufInput.PrematureEofInPackedField.BOOL
-Required.Proto3.ProtobufInput.PrematureEofInPackedField.ENUM
-Required.Proto3.ProtobufInput.PrematureEofInPackedField.INT32
-Required.Proto3.ProtobufInput.PrematureEofInPackedField.INT64
-Required.Proto3.ProtobufInput.PrematureEofInPackedField.SINT32
-Required.Proto3.ProtobufInput.PrematureEofInPackedField.SINT64
-Required.Proto3.ProtobufInput.PrematureEofInPackedField.UINT32
-Required.Proto3.ProtobufInput.PrematureEofInPackedField.UINT64
-Required.Proto2.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE
-Required.Proto2.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE
-Required.Proto2.ProtobufInput.PrematureEofInPackedField.BOOL
-Required.Proto2.ProtobufInput.PrematureEofInPackedField.ENUM
-Required.Proto2.ProtobufInput.PrematureEofInPackedField.INT32
-Required.Proto2.ProtobufInput.PrematureEofInPackedField.INT64
-Required.Proto2.ProtobufInput.PrematureEofInPackedField.SINT32
-Required.Proto2.ProtobufInput.PrematureEofInPackedField.SINT64
-Required.Proto2.ProtobufInput.PrematureEofInPackedField.UINT32
-Required.Proto2.ProtobufInput.PrematureEofInPackedField.UINT64
diff --git a/conformance/failure_list_python_cpp.txt b/conformance/failure_list_python_cpp.txt
index a498ad1..59a969d 100644
--- a/conformance/failure_list_python_cpp.txt
+++ b/conformance/failure_list_python_cpp.txt
@@ -20,35 +20,3 @@
Required.Proto3.JsonInput.FloatFieldTooSmall
Required.Proto3.JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotBool
Required.Proto3.JsonInput.TimestampJsonInputLowercaseT
-Required.Proto3.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE
-Required.Proto3.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE
-Required.Proto3.ProtobufInput.PrematureEofInPackedField.BOOL
-Required.Proto3.ProtobufInput.PrematureEofInPackedField.DOUBLE
-Required.Proto3.ProtobufInput.PrematureEofInPackedField.ENUM
-Required.Proto3.ProtobufInput.PrematureEofInPackedField.FIXED32
-Required.Proto3.ProtobufInput.PrematureEofInPackedField.FIXED64
-Required.Proto3.ProtobufInput.PrematureEofInPackedField.FLOAT
-Required.Proto3.ProtobufInput.PrematureEofInPackedField.INT32
-Required.Proto3.ProtobufInput.PrematureEofInPackedField.INT64
-Required.Proto3.ProtobufInput.PrematureEofInPackedField.SFIXED32
-Required.Proto3.ProtobufInput.PrematureEofInPackedField.SFIXED64
-Required.Proto3.ProtobufInput.PrematureEofInPackedField.SINT32
-Required.Proto3.ProtobufInput.PrematureEofInPackedField.SINT64
-Required.Proto3.ProtobufInput.PrematureEofInPackedField.UINT32
-Required.Proto3.ProtobufInput.PrematureEofInPackedField.UINT64
-Required.Proto2.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE
-Required.Proto2.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE
-Required.Proto2.ProtobufInput.PrematureEofInPackedField.BOOL
-Required.Proto2.ProtobufInput.PrematureEofInPackedField.DOUBLE
-Required.Proto2.ProtobufInput.PrematureEofInPackedField.ENUM
-Required.Proto2.ProtobufInput.PrematureEofInPackedField.FIXED32
-Required.Proto2.ProtobufInput.PrematureEofInPackedField.FIXED64
-Required.Proto2.ProtobufInput.PrematureEofInPackedField.FLOAT
-Required.Proto2.ProtobufInput.PrematureEofInPackedField.INT32
-Required.Proto2.ProtobufInput.PrematureEofInPackedField.INT64
-Required.Proto2.ProtobufInput.PrematureEofInPackedField.SFIXED32
-Required.Proto2.ProtobufInput.PrematureEofInPackedField.SFIXED64
-Required.Proto2.ProtobufInput.PrematureEofInPackedField.SINT32
-Required.Proto2.ProtobufInput.PrematureEofInPackedField.SINT64
-Required.Proto2.ProtobufInput.PrematureEofInPackedField.UINT32
-Required.Proto2.ProtobufInput.PrematureEofInPackedField.UINT64