Down-integrate internal changes (#5467)
* Down-integrate internal changes
* Update generated code for php, objc and csharp.
* Add missing dependency in conformance_php
diff --git a/conformance/Makefile.am b/conformance/Makefile.am
index 29d9a98..97e252e 100644
--- a/conformance/Makefile.am
+++ b/conformance/Makefile.am
@@ -206,7 +206,9 @@
conformance_test_runner_LDADD = $(top_srcdir)/src/libprotobuf.la
conformance_test_runner_SOURCES = conformance_test.h conformance_test.cc \
- conformance_test_impl.cc \
+ binary_json_conformance_main.cc \
+ binary_json_conformance_suite.h \
+ binary_json_conformance_suite.cc \
conformance_test_runner.cc \
third_party/jsoncpp/json.h \
third_party/jsoncpp/jsoncpp.cpp
diff --git a/conformance/binary_json_conformance_main.cc b/conformance/binary_json_conformance_main.cc
new file mode 100644
index 0000000..3e8df73
--- /dev/null
+++ b/conformance/binary_json_conformance_main.cc
@@ -0,0 +1,37 @@
+// 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.
+
+#include "binary_json_conformance_suite.h"
+#include "conformance_test.h"
+
+int main(int argc, char *argv[]) {
+ google::protobuf::BinaryAndJsonConformanceSuite suite;
+ return google::protobuf::ForkPipeRunner::Run(argc, argv, &suite);
+}
diff --git a/conformance/conformance_test_impl.cc b/conformance/binary_json_conformance_suite.cc
similarity index 94%
rename from conformance/conformance_test_impl.cc
rename to conformance/binary_json_conformance_suite.cc
index a884dea..53430a71 100644
--- a/conformance/conformance_test_impl.cc
+++ b/conformance/binary_json_conformance_suite.cc
@@ -28,6 +28,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#include "binary_json_conformance_suite.h"
#include "conformance_test.h"
#include "third_party/jsoncpp/json.h"
@@ -37,11 +38,13 @@
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/strutil.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/wire_format_lite.h>
using conformance::ConformanceRequest;
using conformance::ConformanceResponse;
+using conformance::WireFormat;
using google::protobuf::Descriptor;
using google::protobuf::FieldDescriptor;
using google::protobuf::Message;
@@ -189,73 +192,83 @@
namespace google {
namespace protobuf {
-class ConformanceTestSuiteImpl : public ConformanceTestSuite {
- public:
- ConformanceTestSuiteImpl() {}
+bool BinaryAndJsonConformanceSuite::ParseJsonResponse(
+ const ConformanceResponse& response,
+ Message* test_message) {
+ string binary_protobuf;
+ util::Status status =
+ JsonToBinaryString(type_resolver_.get(), type_url_,
+ response.json_payload(), &binary_protobuf);
- private:
- void RunSuiteImpl();
- void RunValidJsonTest(const string& test_name,
- ConformanceLevel level,
- const string& input_json,
- const string& equivalent_text_format);
- void RunValidJsonTestWithProtobufInput(
- const string& test_name,
- ConformanceLevel level,
- const protobuf_test_messages::proto3::TestAllTypesProto3& input,
- const string& equivalent_text_format);
- void RunValidJsonIgnoreUnknownTest(
- const string& test_name, ConformanceLevel level, const string& input_json,
- const string& equivalent_text_format);
- void RunValidProtobufTest(const string& test_name, ConformanceLevel level,
- const string& input_protobuf,
- const string& equivalent_text_format,
- bool is_proto3);
- void RunValidBinaryProtobufTest(const string& test_name,
- ConformanceLevel level,
- const string& input_protobuf,
- bool is_proto3);
- void RunValidProtobufTestWithMessage(
- const string& test_name, ConformanceLevel level,
- const Message *input,
- const string& equivalent_text_format,
- bool is_proto3);
+ if (!status.ok()) {
+ return false;
+ }
- typedef std::function<bool(const Json::Value&)> Validator;
- void RunValidJsonTestWithValidator(const string& test_name,
- ConformanceLevel level,
- const string& input_json,
- const Validator& validator);
- void ExpectParseFailureForJson(const string& test_name,
- ConformanceLevel level,
- const string& input_json);
- void ExpectSerializeFailureForJson(const string& test_name,
- ConformanceLevel level,
- const string& text_format);
- void ExpectParseFailureForProtoWithProtoVersion (const string& proto,
- const string& test_name,
- ConformanceLevel level,
- bool is_proto3);
- void ExpectParseFailureForProto(const std::string& proto,
- const std::string& test_name,
- ConformanceLevel level);
- void ExpectHardParseFailureForProto(const std::string& proto,
- const std::string& test_name,
- ConformanceLevel level);
- void TestPrematureEOFForType(google::protobuf::FieldDescriptor::Type type);
- void TestIllegalTags();
- template <class MessageType>
- void TestOneofMessage (MessageType &message,
- bool is_proto3);
- template <class MessageType>
- void TestUnknownMessage (MessageType &message,
- bool is_proto3);
- void TestValidDataForType(
- google::protobuf::FieldDescriptor::Type,
- std::vector<std::pair<std::string, std::string>> values);
-};
+ if (!test_message->ParseFromString(binary_protobuf)) {
+ GOOGLE_LOG(FATAL)
+ << "INTERNAL ERROR: internal JSON->protobuf transcode "
+ << "yielded unparseable proto.";
+ return false;
+ }
-void ConformanceTestSuiteImpl::ExpectParseFailureForProtoWithProtoVersion (
+ return true;
+}
+
+bool BinaryAndJsonConformanceSuite::ParseResponse(
+ const ConformanceResponse& response,
+ const ConformanceRequestSetting& setting,
+ Message* test_message) {
+ const ConformanceRequest& request = setting.GetRequest();
+ WireFormat requested_output = request.requested_output_format();
+ const string& test_name = setting.GetTestName();
+ ConformanceLevel level = setting.GetLevel();
+
+ switch (response.result_case()) {
+ case ConformanceResponse::kProtobufPayload: {
+ if (requested_output != conformance::PROTOBUF) {
+ ReportFailure(
+ test_name, level, request, response,
+ StrCat("Test was asked for ", WireFormatToString(requested_output),
+ " output but provided PROTOBUF instead.").c_str());
+ return false;
+ }
+
+ if (!test_message->ParseFromString(response.protobuf_payload())) {
+ ReportFailure(test_name, level, request, response,
+ "Protobuf output we received from test was unparseable.");
+ return false;
+ }
+
+ break;
+ }
+
+ case ConformanceResponse::kJsonPayload: {
+ if (requested_output != conformance::JSON) {
+ ReportFailure(
+ test_name, level, request, response,
+ StrCat("Test was asked for ", WireFormatToString(requested_output),
+ " output but provided JSON instead.").c_str());
+ return false;
+ }
+
+ if (!ParseJsonResponse(response, test_message)) {
+ ReportFailure(test_name, level, request, response,
+ "JSON output we received from test was unparseable.");
+ return false;
+ }
+
+ break;
+ }
+
+ default:
+ GOOGLE_LOG(FATAL) << test_name << ": unknown payload type: "
+ << response.result_case();
+ }
+
+ return true;
+}
+
+void BinaryAndJsonConformanceSuite::ExpectParseFailureForProtoWithProtoVersion (
const string& proto, const string& test_name, ConformanceLevel level,
bool is_proto3) {
std::unique_ptr<Message> prototype = NewTestMessage(is_proto3);
@@ -285,7 +298,7 @@
}
// Expect that this precise protobuf will cause a parse error.
-void ConformanceTestSuiteImpl::ExpectParseFailureForProto(
+void BinaryAndJsonConformanceSuite::ExpectParseFailureForProto(
const string& proto, const string& test_name, ConformanceLevel level) {
ExpectParseFailureForProtoWithProtoVersion(proto, test_name, level, true);
ExpectParseFailureForProtoWithProtoVersion(proto, test_name, level, false);
@@ -296,12 +309,12 @@
// data verbatim and once with this data followed by some valid data.
//
// TODO(haberman): implement the second of these.
-void ConformanceTestSuiteImpl::ExpectHardParseFailureForProto(
+void BinaryAndJsonConformanceSuite::ExpectHardParseFailureForProto(
const string& proto, const string& test_name, ConformanceLevel level) {
return ExpectParseFailureForProto(proto, test_name, level);
}
-void ConformanceTestSuiteImpl::RunValidJsonTest(
+void BinaryAndJsonConformanceSuite::RunValidJsonTest(
const string& test_name, ConformanceLevel level, const string& input_json,
const string& equivalent_text_format) {
TestAllTypesProto3 prototype;
@@ -317,7 +330,7 @@
RunValidInputTest(setting2, equivalent_text_format);
}
-void ConformanceTestSuiteImpl::RunValidJsonTestWithProtobufInput(
+void BinaryAndJsonConformanceSuite::RunValidJsonTestWithProtobufInput(
const string& test_name, ConformanceLevel level, const TestAllTypesProto3& input,
const string& equivalent_text_format) {
ConformanceRequestSetting setting(
@@ -327,7 +340,7 @@
RunValidInputTest(setting, equivalent_text_format);
}
-void ConformanceTestSuiteImpl::RunValidJsonIgnoreUnknownTest(
+void BinaryAndJsonConformanceSuite::RunValidJsonIgnoreUnknownTest(
const string& test_name, ConformanceLevel level, const string& input_json,
const string& equivalent_text_format) {
TestAllTypesProto3 prototype;
@@ -338,7 +351,7 @@
RunValidInputTest(setting, equivalent_text_format);
}
-void ConformanceTestSuiteImpl::RunValidProtobufTest(
+void BinaryAndJsonConformanceSuite::RunValidProtobufTest(
const string& test_name, ConformanceLevel level,
const string& input_protobuf, const string& equivalent_text_format,
bool is_proto3) {
@@ -359,7 +372,7 @@
}
}
-void ConformanceTestSuiteImpl::RunValidBinaryProtobufTest(
+void BinaryAndJsonConformanceSuite::RunValidBinaryProtobufTest(
const string& test_name, ConformanceLevel level,
const string& input_protobuf, bool is_proto3) {
std::unique_ptr<Message> prototype = NewTestMessage(is_proto3);
@@ -370,7 +383,7 @@
RunValidBinaryInputTest(setting, input_protobuf);
}
-void ConformanceTestSuiteImpl::RunValidProtobufTestWithMessage(
+void BinaryAndJsonConformanceSuite::RunValidProtobufTestWithMessage(
const string& test_name, ConformanceLevel level, const Message *input,
const string& equivalent_text_format, bool is_proto3) {
RunValidProtobufTest(test_name, level, input->SerializeAsString(),
@@ -382,7 +395,7 @@
// numbers while the parser is allowed to accept them as JSON strings). This
// method allows strict checking on a proto3 JSON serializer by inspecting
// the JSON output directly.
-void ConformanceTestSuiteImpl::RunValidJsonTestWithValidator(
+void BinaryAndJsonConformanceSuite::RunValidJsonTestWithValidator(
const string& test_name, ConformanceLevel level, const string& input_json,
const Validator& validator) {
TestAllTypesProto3 prototype;
@@ -426,7 +439,7 @@
ReportSuccess(effective_test_name);
}
-void ConformanceTestSuiteImpl::ExpectParseFailureForJson(
+void BinaryAndJsonConformanceSuite::ExpectParseFailureForJson(
const string& test_name, ConformanceLevel level, const string& input_json) {
TestAllTypesProto3 prototype;
// We don't expect output, but if the program erroneously accepts the protobuf
@@ -452,7 +465,7 @@
}
}
-void ConformanceTestSuiteImpl::ExpectSerializeFailureForJson(
+void BinaryAndJsonConformanceSuite::ExpectSerializeFailureForJson(
const string& test_name, ConformanceLevel level, const string& text_format) {
TestAllTypesProto3 payload_message;
GOOGLE_CHECK(
@@ -482,7 +495,7 @@
}
//TODO: proto2?
-void ConformanceTestSuiteImpl::TestPrematureEOFForType(
+void BinaryAndJsonConformanceSuite::TestPrematureEOFForType(
FieldDescriptor::Type type) {
// Incomplete values for each wire type.
static const string incompletes[6] = {
@@ -570,7 +583,7 @@
}
}
-void ConformanceTestSuiteImpl::TestValidDataForType(
+void BinaryAndJsonConformanceSuite::TestValidDataForType(
FieldDescriptor::Type type,
std::vector<std::pair<std::string, std::string>> values) {
for (int is_proto3 = 0; is_proto3 < 2; is_proto3++) {
@@ -606,7 +619,7 @@
}
// TODO: proto2?
-void ConformanceTestSuiteImpl::TestIllegalTags() {
+void BinaryAndJsonConformanceSuite::TestIllegalTags() {
// field num 0 is illegal
string nullfield[] = {
"\1DEADBEEF",
@@ -621,7 +634,7 @@
}
}
template <class MessageType>
-void ConformanceTestSuiteImpl::TestOneofMessage (
+void BinaryAndJsonConformanceSuite::TestOneofMessage (
MessageType &message, bool is_proto3) {
message.set_oneof_uint32(0);
RunValidProtobufTestWithMessage(
@@ -660,14 +673,14 @@
}
template <class MessageType>
-void ConformanceTestSuiteImpl::TestUnknownMessage(
+void BinaryAndJsonConformanceSuite::TestUnknownMessage(
MessageType& message, bool is_proto3) {
message.ParseFromString("\xA8\x1F\x01");
RunValidBinaryProtobufTest("UnknownVarint", REQUIRED,
message.SerializeAsString(), is_proto3);
}
-void ConformanceTestSuiteImpl::RunSuiteImpl() {
+void BinaryAndJsonConformanceSuite::RunSuiteImpl() {
type_resolver_.reset(NewTypeResolverForDescriptorPool(
kTypeUrlPrefix, DescriptorPool::generated_pool()));
type_url_ = GetTypeUrl(TestAllTypesProto3::descriptor());
@@ -2360,8 +2373,3 @@
} // namespace protobuf
} // namespace google
-
-int main(int argc, char *argv[]) {
- google::protobuf::ConformanceTestSuiteImpl suite;
- return google::protobuf::ForkPipeRunner::Run(argc, argv, &suite);
-}
diff --git a/conformance/binary_json_conformance_suite.h b/conformance/binary_json_conformance_suite.h
new file mode 100644
index 0000000..7a03545
--- /dev/null
+++ b/conformance/binary_json_conformance_suite.h
@@ -0,0 +1,121 @@
+// 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.
+
+#ifndef CONFORMANCE_BINARY_JSON_CONFORMANCE_SUITE_H
+#define CONFORMANCE_BINARY_JSON_CONFORMANCE_SUITE_H
+
+#include "conformance_test.h"
+#include "third_party/jsoncpp/json.h"
+
+namespace google {
+namespace protobuf {
+
+class BinaryAndJsonConformanceSuite : public ConformanceTestSuite {
+ public:
+ BinaryAndJsonConformanceSuite() {}
+
+ private:
+ void RunSuiteImpl();
+ void RunValidJsonTest(const string& test_name,
+ ConformanceLevel level,
+ const string& input_json,
+ const string& equivalent_text_format);
+ void RunValidJsonTestWithProtobufInput(
+ const string& test_name,
+ ConformanceLevel level,
+ const protobuf_test_messages::proto3::TestAllTypesProto3& input,
+ const string& equivalent_text_format);
+ void RunValidJsonIgnoreUnknownTest(
+ const string& test_name, ConformanceLevel level, const string& input_json,
+ const string& equivalent_text_format);
+ void RunValidProtobufTest(const string& test_name, ConformanceLevel level,
+ const string& input_protobuf,
+ const string& equivalent_text_format,
+ bool is_proto3);
+ void RunValidBinaryProtobufTest(const string& test_name,
+ ConformanceLevel level,
+ const string& input_protobuf,
+ bool is_proto3);
+ void RunValidProtobufTestWithMessage(
+ const string& test_name, ConformanceLevel level,
+ const Message *input,
+ const string& equivalent_text_format,
+ bool is_proto3);
+
+ bool ParseJsonResponse(
+ const conformance::ConformanceResponse& response,
+ Message* test_message);
+ bool ParseResponse(
+ const conformance::ConformanceResponse& response,
+ const ConformanceRequestSetting& setting,
+ Message* test_message) override;
+
+ typedef std::function<bool(const Json::Value&)> Validator;
+ void RunValidJsonTestWithValidator(const string& test_name,
+ ConformanceLevel level,
+ const string& input_json,
+ const Validator& validator);
+ void ExpectParseFailureForJson(const string& test_name,
+ ConformanceLevel level,
+ const string& input_json);
+ void ExpectSerializeFailureForJson(const string& test_name,
+ ConformanceLevel level,
+ const string& text_format);
+ void ExpectParseFailureForProtoWithProtoVersion (const string& proto,
+ const string& test_name,
+ ConformanceLevel level,
+ bool is_proto3);
+ void ExpectParseFailureForProto(const std::string& proto,
+ const std::string& test_name,
+ ConformanceLevel level);
+ void ExpectHardParseFailureForProto(const std::string& proto,
+ const std::string& test_name,
+ ConformanceLevel level);
+ void TestPrematureEOFForType(google::protobuf::FieldDescriptor::Type type);
+ void TestIllegalTags();
+ template <class MessageType>
+ void TestOneofMessage (MessageType &message,
+ bool is_proto3);
+ template <class MessageType>
+ void TestUnknownMessage (MessageType &message,
+ bool is_proto3);
+ void TestValidDataForType(
+ google::protobuf::FieldDescriptor::Type,
+ std::vector<std::pair<std::string, std::string>> values);
+
+ std::unique_ptr<google::protobuf::util::TypeResolver>
+ type_resolver_;
+ std::string type_url_;
+};
+
+} // namespace protobuf
+} // namespace google
+
+#endif // CONFORMANCE_BINARY_JSON_CONFORMANCE_SUITE_H
diff --git a/conformance/conformance.proto b/conformance/conformance.proto
index af89152..b0dc762 100644
--- a/conformance/conformance.proto
+++ b/conformance/conformance.proto
@@ -55,6 +55,7 @@
UNSPECIFIED = 0;
PROTOBUF = 1;
JSON = 2;
+ JSPB = 3; // Google internal only. Opensource testees just skip it.
}
enum TestCategory {
@@ -67,6 +68,8 @@
// https://developers.google.com/protocol-buffers/docs/proto3#json_options
// for more detail.
JSON_IGNORE_UNKNOWN_PARSING_TEST = 3;
+ JSPB_TEST = 4; // Test jspb wire format. Google internal only.
+ // Opensource testees just skip it.
}
// Represents a single test case's input. The testee should:
@@ -85,6 +88,8 @@
oneof payload {
bytes protobuf_payload = 1;
string json_payload = 2;
+ string jspb_payload = 7; // Google internal only.
+ // Opensource testees just skip it.
}
// Which format should the testee serialize its message to?
@@ -99,6 +104,9 @@
// spedific support in testee programs. Refer to the defintion of TestCategory
// for more information.
TestCategory test_category = 5;
+
+ // Specify details for how to encode jspb.
+ JspbEncodingConfig jspb_encoding_options = 6;
}
// Represents a single test case's output.
@@ -132,5 +140,16 @@
// For when the testee skipped the test, likely because a certain feature
// wasn't supported, like JSON input/output.
string skipped = 5;
+
+ // If the input was successfully parsed and the requested output was JSPB,
+ // serialize to JSPB and set it in this field. JSPB is google internal only
+ // format. Opensource testees can just skip it.
+ string jspb_payload = 7;
}
}
+
+// Encoding options for jspb format.
+message JspbEncodingConfig {
+ // Encode the value field of Any as jspb array if ture, otherwise binary.
+ bool use_jspb_array_any_format = 1;
+}
diff --git a/conformance/conformance_cpp.cc b/conformance/conformance_cpp.cc
index ac2f6de..ce333ee 100644
--- a/conformance/conformance_cpp.cc
+++ b/conformance/conformance_cpp.cc
@@ -137,6 +137,11 @@
case ConformanceRequest::PAYLOAD_NOT_SET:
GOOGLE_LOG(FATAL) << "Request didn't have payload.";
break;
+
+ default:
+ GOOGLE_LOG(FATAL) << "unknown payload type: "
+ << request.payload_case();
+ break;
}
switch (request.requested_output_format()) {
diff --git a/conformance/conformance_php.php b/conformance/conformance_php.php
index 799cc3e..cc6d4b9 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/JspbEncodingConfig.php");
require_once("Conformance/TestCategory.php");
require_once("Protobuf_test_messages/Proto3/ForeignMessage.php");
require_once("Protobuf_test_messages/Proto3/ForeignEnum.php");
diff --git a/conformance/conformance_test.cc b/conformance/conformance_test.cc
index 2d822c2..68b813d 100644
--- a/conformance/conformance_test.cc
+++ b/conformance/conformance_test.cc
@@ -80,6 +80,11 @@
break;
}
+ case conformance::JSPB: {
+ request_.set_jspb_payload(input);
+ break;
+ }
+
default:
GOOGLE_LOG(FATAL) << "Unspecified input format";
}
@@ -215,23 +220,27 @@
void ConformanceTestSuite::RunValidBinaryInputTest(
const ConformanceRequestSetting& setting,
const string& equivalent_wire_format) {
+ const ConformanceRequest& request = setting.GetRequest();
+ ConformanceResponse response;
+ RunTest(setting.GetTestName(), request, &response);
+ VerifyResponse(setting, equivalent_wire_format, response, true);
+}
+
+void ConformanceTestSuite::VerifyResponse(
+ const ConformanceRequestSetting& setting,
+ const string& equivalent_wire_format,
+ const ConformanceResponse& response,
+ bool need_report_success) {
+ Message* test_message = setting.GetTestMessage();
+ const ConformanceRequest& request = setting.GetRequest();
const string& test_name = setting.GetTestName();
ConformanceLevel level = setting.GetLevel();
-
Message* reference_message = setting.GetTestMessage();
+
GOOGLE_CHECK(
reference_message->ParseFromString(equivalent_wire_format))
<< "Failed to parse wire data for test case: " << test_name;
- const ConformanceRequest& request = setting.GetRequest();
- ConformanceResponse response;
-
- RunTest(test_name, request, &response);
-
- Message* test_message = setting.GetTestMessage();
-
- WireFormat requested_output = request.requested_output_format();
-
switch (response.result_case()) {
case ConformanceResponse::RESULT_NOT_SET:
ReportFailure(test_name, level, request, response,
@@ -249,53 +258,8 @@
ReportSkip(test_name, request, response);
return;
- case ConformanceResponse::kJsonPayload: {
- if (requested_output != conformance::JSON) {
- ReportFailure(
- test_name, level, request, response,
- "Test was asked for protobuf output but provided JSON instead.");
- return;
- }
- string binary_protobuf;
- Status status =
- JsonToBinaryString(type_resolver_.get(), type_url_,
- response.json_payload(), &binary_protobuf);
- if (!status.ok()) {
- ReportFailure(test_name, level, request, response,
- "JSON output we received from test was unparseable.");
- return;
- }
-
- if (!test_message->ParseFromString(binary_protobuf)) {
- ReportFailure(test_name, level, request, response,
- "INTERNAL ERROR: internal JSON->protobuf transcode "
- "yielded unparseable proto.");
- return;
- }
-
- break;
- }
-
- case ConformanceResponse::kProtobufPayload: {
- if (requested_output != conformance::PROTOBUF) {
- ReportFailure(
- test_name, level, request, response,
- "Test was asked for JSON output but provided protobuf instead.");
- return;
- }
-
- if (!test_message->ParseFromString(response.protobuf_payload())) {
- ReportFailure(test_name, level, request, response,
- "Protobuf output we received from test was unparseable.");
- return;
- }
-
- break;
- }
-
default:
- GOOGLE_LOG(FATAL) << test_name << ": unknown payload type: "
- << response.result_case();
+ if (!ParseResponse(response, setting, test_message)) return;
}
MessageDifferencer differencer;
@@ -308,7 +272,9 @@
bool check;
check = differencer.Compare(*reference_message, *test_message);
if (check) {
- ReportSuccess(test_name);
+ if (need_report_success) {
+ ReportSuccess(test_name);
+ }
} else {
ReportFailure(test_name, level, request, response,
"Output was not equivalent to reference message: %s.",
@@ -375,6 +341,24 @@
}
}
+string ConformanceTestSuite::WireFormatToString(
+ WireFormat wire_format) {
+ switch (wire_format) {
+ case conformance::PROTOBUF:
+ return "PROTOBUF";
+ case conformance::JSON:
+ return "JSON";
+ case conformance::JSPB:
+ return "JSPB";
+ case conformance::UNSPECIFIED:
+ return "UNSPECIFIED";
+ default:
+ GOOGLE_LOG(FATAL) << "unknown wire type: "
+ << wire_format;
+ }
+ return "";
+}
+
bool ConformanceTestSuite::RunSuite(
ConformanceTestRunner* runner, std::string* output) {
runner_ = runner;
diff --git a/conformance/conformance_test.h b/conformance/conformance_test.h
index d5c2f3d..ab82bbe 100644
--- a/conformance/conformance_test.h
+++ b/conformance/conformance_test.h
@@ -87,7 +87,6 @@
static int Run(int argc, char *argv[],
ConformanceTestSuite* suite);
- private:
ForkPipeRunner(const std::string &executable)
: child_pid_(-1), executable_(executable) {}
@@ -97,24 +96,7 @@
const std::string& request,
std::string* response);
- // TODO(haberman): make this work on Windows, instead of using these
- // UNIX-specific APIs.
- //
- // There is a platform-agnostic API in
- // src/google/protobuf/compiler/subprocess.h
- //
- // However that API only supports sending a single message to the subprocess.
- // We really want to be able to send messages and receive responses one at a
- // time:
- //
- // 1. Spawning a new process for each test would take way too long for thousands
- // of tests and subprocesses like java that can take 100ms or more to start
- // up.
- //
- // 2. Sending all the tests in one big message and receiving all results in one
- // big message would take away our visibility about which test(s) caused a
- // crash or other fatal error. It would also give us only a single failure
- // instead of all of them.
+ private:
void SpawnTestProgram();
void CheckedWrite(int fd, const void *buf, size_t len);
@@ -237,6 +219,7 @@
protected:
virtual string InputFormatString(conformance::WireFormat format) const;
virtual string OutputFormatString(conformance::WireFormat format) const;
+ conformance::ConformanceRequest request_;
private:
ConformanceLevel level_;
@@ -244,11 +227,24 @@
::conformance::WireFormat output_format_;
const Message& prototype_message_;
string test_name_;
- conformance::ConformanceRequest request_;
};
bool CheckSetEmpty(const std::set<string>& set_to_check,
const std::string& write_to_file, const std::string& msg);
+ string WireFormatToString(conformance::WireFormat wire_format);
+
+ // Parse payload in the response to the given message. Returns true on
+ // success.
+ virtual bool ParseResponse(
+ const conformance::ConformanceResponse& response,
+ const ConformanceRequestSetting& setting,
+ Message* test_message) = 0;
+
+ void VerifyResponse(
+ const ConformanceRequestSetting& setting,
+ const string& equivalent_wire_format,
+ const conformance::ConformanceResponse& response,
+ bool need_report_success);
void ReportSuccess(const std::string& test_name);
void ReportFailure(const string& test_name,
@@ -295,10 +291,6 @@
// The set of tests that the testee opted out of;
std::set<std::string> skipped_;
-
- std::unique_ptr<google::protobuf::util::TypeResolver>
- type_resolver_;
- std::string type_url_;
};
} // namespace protobuf
diff --git a/conformance/conformance_test_runner.cc b/conformance/conformance_test_runner.cc
index 9c37712..8b44752 100644
--- a/conformance/conformance_test_runner.cc
+++ b/conformance/conformance_test_runner.cc
@@ -212,6 +212,24 @@
return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
+// TODO(haberman): make this work on Windows, instead of using these
+// UNIX-specific APIs.
+//
+// There is a platform-agnostic API in
+// src/google/protobuf/compiler/subprocess.h
+//
+// However that API only supports sending a single message to the subprocess.
+// We really want to be able to send messages and receive responses one at a
+// time:
+//
+// 1. Spawning a new process for each test would take way too long for thousands
+// of tests and subprocesses like java that can take 100ms or more to start
+// up.
+//
+// 2. Sending all the tests in one big message and receiving all results in one
+// big message would take away our visibility about which test(s) caused a
+// crash or other fatal error. It would also give us only a single failure
+// instead of all of them.
void ForkPipeRunner::SpawnTestProgram() {
int toproc_pipe_fd[2];
int fromproc_pipe_fd[2];